Microblaze libgloss and gdb simulator
Mike Frysinger
vapier@gentoo.org
Sun Apr 25 17:21:58 GMT 2021
On 24 Apr 2021 01:02, Mike Frysinger via Gdb wrote:
> On 22 Apr 2021 21:19, Mike Frysinger via Gdb wrote:
> > On 22 Apr 2021 19:55, Joel Sherrill wrote:
> > > On Thu, Apr 22, 2021, 7:27 PM Mike Frysinger wrote:
> > > > ignoring that, the microblaze sim doesn't have syscall support hooked up.
> > > > so it's only a CPU simulator atm.
> > >
> > > So it has no output whatsoever? Does it get used for anything?
> >
> > afaict, correct. the most basic sims just do CPU level stuff and then have
> > their state inspected, or communicate pass/fail via exit status or abort.
> > this behavior actually isn't that rare ... it's where most sims start.
> >
> > > We are resurrecting some old work that I did for a Microblaze port. I did
> > > write an inbyte() and outbyte() which would normally come from the xil
> > > library. But I don't have any idea how I figured out there was a uart at a
> > > particular address. I swear I had it working to print then but now it
> > > faults after the first instruction.
> > >
> > > Is there any known good executable for it? Even just seeing it operate with
> > > a linked executable that had a crt0 and did something would be helpful at
> > > this point.
> >
> > ftr, i've never worked on microblaze. i'm just reading the code and poking
> > the toolchain :).
> >
> > getting i/o (or maybe just o) support into the sim shouldn't be terribly hard.
> > we could even do the normal libgloss syscalls. the important things we need to
> > know are:
> > * how does outbyte work ? is it writing to MMIO UARTs, or something else ?
> > * is there an interrupt or exception or specific insn that microblaze uses to
> > trigger the hypervisor/monitor/whatever ? if so, should be possible to wire
> > that up in the microblaze port. my reading of libgloss/microblaze/ isn't
> > picking out anything interesting, but i'm by no means an expert here.
> >
> > if you can figure out those bits, happy to help on the sim side.
>
> here's wiring up the syscall path, but it's unclear whether we should do this
> without changes landing in libgloss first.
Michael: what do you think of wiring up the libgloss syscalls for microblaze
via the brki insn ? is there any prior art in this space for microblaze ?
i wouldn't want to try an allocate syscall space that's already used.
-mike
> --- a/sim/common/gennltvals.py
> +++ b/sim/common/gennltvals.py
> @@ -66,6 +66,7 @@ TARGETS = {
> 'm32c',
> 'm32r',
> 'mcore',
> + 'microblaze',
> 'mn10200',
> 'mn10300',
> 'moxie',
> --- a/sim/common/nltvals.def
> +++ b/sim/common/nltvals.def
> @@ -484,6 +484,37 @@
> /* end mcore sys target macros */
> #endif
> #endif
> +#ifdef NL_TARGET_microblaze
> +#ifdef sys_defs
> +/* from syscall.h */
> +/* begin microblaze sys target macros */
> + { "SYS_argc", 22 },
> + { "SYS_argn", 24 },
> + { "SYS_argnlen", 23 },
> + { "SYS_argv", 13 },
> + { "SYS_argvlen", 12 },
> + { "SYS_chdir", 14 },
> + { "SYS_chmod", 16 },
> + { "SYS_close", 3 },
> + { "SYS_exit", 1 },
> + { "SYS_fstat", 10 },
> + { "SYS_getpid", 8 },
> + { "SYS_gettimeofday", 19 },
> + { "SYS_kill", 9 },
> + { "SYS_link", 21 },
> + { "SYS_lseek", 6 },
> + { "SYS_open", 2 },
> + { "SYS_read", 4 },
> + { "SYS_reconfig", 25 },
> + { "SYS_stat", 15 },
> + { "SYS_time", 18 },
> + { "SYS_times", 20 },
> + { "SYS_unlink", 7 },
> + { "SYS_utime", 17 },
> + { "SYS_write", 5 },
> +/* end microblaze sys target macros */
> +#endif
> +#endif
> #ifdef NL_TARGET_mn10200
> #ifdef sys_defs
> /* from syscall.h */
> --- a/sim/microblaze/Makefile.in
> +++ b/sim/microblaze/Makefile.in
> @@ -15,6 +15,9 @@
> # You should have received a copy of the GNU General Public License
> # along with this program. If not, see <http://www.gnu.org/licenses/>.
>
> +# This selects the bfin newlib/libgloss syscall definitions.
> +NL_TARGET = -DNL_TARGET_microblaze
> +
> ## COMMON_PRE_CONFIG_FRAG
>
> SIM_OBJS = \
> diff --git a/sim/microblaze/interp.c b/sim/microblaze/interp.c
> index 2bd067c6dc51..ed29d020efbc 100644
> --- a/sim/microblaze/interp.c
> +++ b/sim/microblaze/interp.c
> @@ -28,6 +28,7 @@
>
> #include "sim-main.h"
> #include "sim-options.h"
> +#include "sim-syscall.h"
>
> #include "microblaze-dis.h"
>
> @@ -162,11 +163,14 @@ sim_engine_run (SIM_DESC sd,
> delay_slot_enable = 0;
> branch_taken = 0;
> if (op == microblaze_brk)
> - sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
> + {
> + sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
> + }
> else if (inst == MICROBLAZE_HALT_INST)
> {
> insts += 1;
> bonus_cycles++;
> + TRACE_INSN (cpu, "HALT (%i)", RETREG);
> sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_exited, RETREG);
> }
> else
> @@ -175,6 +179,7 @@ sim_engine_run (SIM_DESC sd,
> {
> #define INSTRUCTION(NAME, OPCODE, TYPE, ACTION) \
> case NAME: \
> + TRACE_INSN (cpu, #NAME); \
> ACTION; \
> break;
> #include "microblaze.isa"
> @@ -284,8 +289,18 @@ sim_engine_run (SIM_DESC sd,
> IMM_ENABLE = 0;
> }
> else
> - /* no delay slot: increment cycle count */
> - bonus_cycles++;
> + {
> + if (op == brki)
> + {
> + RETREG = sim_syscall (cpu, CPU.regs[12], CPU.regs[5],
> + CPU.regs[6], CPU.regs[7],
> + CPU.regs[8]);
> + PC = RD + INST_SIZE;
> + }
> +
> + /* no delay slot: increment cycle count */
> + bonus_cycles++;
> + }
> }
> }
>
> --- a/sim/microblaze/microblaze.isa
> +++ b/sim/microblaze/microblaze.isa
> @@ -110,6 +110,7 @@ INSTRUCTION(addi,
> INST_TYPE_RD_RA_IMM,
> CARRY = C_calc(RA, IMM, 0);
> RD = RA + IMM;
> + TRACE_REGISTER (cpu, "r%i = r%i + %i", rd, ra, IMM);
> C_wr(CARRY);
> PC += INST_SIZE)
>
> --- a/sim/testsuite/microblaze/pass.s
> +++ b/sim/testsuite/microblaze/pass.s
> @@ -1,6 +1,5 @@
> # check that the sim doesn't die immediately.
> # mach: microblaze
> -# output:
>
> .include "testutils.inc"
>
> --- a/sim/testsuite/microblaze/testutils.inc
> +++ b/sim/testsuite/microblaze/testutils.inc
> @@ -1,5 +1,12 @@
> +# MACRO: system_call
> +# Make a libgloss/Linux system call
> + .macro system_call nr:req
> + addi r12, r0, \nr;
> + brki r14, 8;
> + .endm
> +
> # MACRO: exit
> - .macro exit nr
> + .macro exit nr:req
> addi r3, r0, \nr;
> bri 0;
> .endm
> @@ -7,6 +14,7 @@
> # MACRO: pass
> # Write 'pass' to stdout and quit
> .macro pass
> + write 1, 1f, 5
> exit 0
> .data
> 1: .asciz "pass\n"
> @@ -15,6 +23,7 @@
> # MACRO: fail
> # Write 'fail' to stdout and quit
> .macro fail
> + write 1, 1f, 5
> exit 1
> .data
> 1: .asciz "fail\n"
> @@ -27,3 +36,12 @@
> .global _start
> _start:
> .endm
> +
> +# MACRO: write
> +# Just like the write() C function; uses system calls
> + .macro write fd:req, buf:req, count:req
> + addi r5, r0, \fd;
> + addi r6, r0, \buf;
> + addi r7, r0, \count;
> + system_call 5
> + .endm
More information about the Gdb
mailing list