RTEMS5, QEMU, Leon3, and AMBA PnP tables
John Clemens
john.clemens at jhuapl.edu
Tue Feb 22 14:43:20 UTC 2022
Hello,
I've been trying to make sparc-rtems5 demo programs work on the latest
QEMU/Leon3 model, and I've finally succeeded.
Currently, if you run a demo program like ticker.exe on the upstream
QEMU master branch using the leon3_generic model, the program exits very
early on because it cannot find the interrupt controller by parsing the
AMBA APB entries, leading to `bsp_fatal()` in
bsps/sparc/leon3/start/amba.c:98 .
I tracked this down to the memcpy failing to copy the APB struct from
the AMBA PNP table when it makes its local copy in
bsps/shared/grlib/amba/ambapp.c, roughly around line 253. Using a
debugger, the result in apb_buf after the memfunc() call is always:
{ id = 0x01010101, iobase = 0x0. }
..regardless of what is actually supposed to be there, for example
here's the output from gdb of the two values, which should be identical:
28: (struct ambapp_pnp_apb)(*apb) = {id = 0x100c023, iobar = 0x10fff1}
29: apb_buf = {id = 0x1010101, iobar = 0x0}
However, since the values in the apb pointer in the same code are
accurate, you can replace the memfunc() call with something silly like:
unsigned int dummy[2] = { apb->id, apb->iobar };
.. and then use `dummy` instead of apb_buf where needed later in that
code block and have everything work as intended.
I suspect this has to do with QEMU's memory read functions for the AHB
and APB regions being declared as word (4-byte) access only, while I
suspect the memcpy() function uses byte access. Notice how the corrupted
values appear to be the first byte of the correct value repeated 4
times. QEMU's memory area functions are (from hw/misc/grlib_ahv_apb_pnp.c):
static uint64_t grlib_apb_pnp_read(void *opaque, hwaddr offset, unsigned
size)
{
APBPnp *apb_pnp = GRLIB_APB_PNP(opaque);
uint32_t val;
val = apb_pnp->regs[offset >> 2];
trace_grlib_apb_pnp_read(offset, val);
return val;
}
static const MemoryRegionOps grlib_apb_pnp_ops = {
.read = grlib_apb_pnp_read,
.write = grlib_apb_pnp_write,
.endianness = DEVICE_BIG_ENDIAN,
.impl = {
.min_access_size = 4,
.max_access_size = 4,
},
};
... so the access is limited to word accesses, and it looks like the
read function would need to be tweaked to allow byte access.
So this leads to some questions:
- Is my breakdown correct?
- Why is RTEMS copying this table into ram before parsing, why not just
parse it directly?
- Are there real systems that limit the memory that the PNP tables are
stored in to word access only? Or is this a quirk of QEMU?
- Why does there not *appear* to be an issue when parsing the AHB
entries, when they use the same access pattern? (perhaps there is and
I've just been lucky so far)
- On real leon3 hardware, which behavior is more correct? the QEMU model
or the one RTEMS expects?
I suspect this is a case where QEMU needs to be updated to allow byte
access, but would appreciate any clarification the RTEMS team can give.
Thanks for any insight,
john.c
--
John Clemens <john.clemens at jhuapl.edu>
More information about the users
mailing list