Open neuschaefer opened 3 years ago
Based on this FOSDEM presentation, there isn't any 'nice' way to translate a device tree directly into any of the QEMU device APIs, so a QEMU config would have to be built by hand. Still, I agree, it'd be very nice to verify booting works in QEMU before flashing the build directly e.g. to a motherboard.
peripherals of NPCM7xx can probably be reused.
In what sense? Has a QEMU config already been set up for the NPCM7xx?
QEMU already has peripheral device implementations and SoC/board configs for NPCM750:
$ qemu-system-arm -M ? | grep NPCM
npcm750-evb Nuvoton NPCM750 Evaluation Board (Cortex A9)
The configurations are probably too specific to the NPCM750(-evb) to reuse, but some of the device emulation code (e.g. I2C) can probably be reused.
I may be misunderstanding what you mean by a "QEMU config". If that's the case, please elaborate.
No, you understood me correctly. I actually was not actually really cognizant that the Qemu Object Model actually gets used using C code. Thanks for the links to the SoC and boards.
So would a good way to build the device in QEMU be to loop through the following?:
1) take a minimal default QEMU arm32 SoC + Board, 2) rebuild Linux using select patches from your tree, where applicable 3) migrate an item described in the final device tree into both the compiled-in device tree and into the SoC / board config 4) rebuild qemu 5) Repeat from step 2
Sounds like an approach that should work.
For an absolutely minimal configuration, I think you'll need:
If you have any questions regarding how a peripheral works, please use the wiki and/or raise issues with the "Documentation" tag. I'll be happy to help!
I take versatile board like base board and take some code from npcm7xx board, change base address and irq from your wiki.
Your 2 bare-metal programs (screem and monitor) your for UART0 output with serail0 on qemu but output not work. I just configure UART address, so i think is important to configure interrupt controller and timer correctly for make monitor work correctly.
I continue to work on and publish as soon as possible the modification on github.
Thanks for you work
Hi @StidOfficial, The scream program only accesses the UART. I think it's a good first test case, because it is (almost) the simplest possible test program. The monitor accesses the UART and the timer, but not the interrupt controller, so it should, at this point, not be necessary to hook up the interrupt controller.
The npcm7xx_timer are the same but the mapping for timers and watchdogs are completly diffrent for the npcm7xx.
For the bases addresses : https://github.com/qemu/qemu/blob/52fecb866923890b16202be8e0f360bf247db6a7/hw/arm/npcm7xx.c#L147-L152 With have only 1 address for timers on 0xb8001000 ?
For timers device and sysbuse : https://github.com/qemu/qemu/blob/master/hw/arm/npcm7xx.c#L530-L558 For monitor we the need to do :
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->tim);
/* Connect the timer clock. */
qdev_connect_clock_in(DEVICE(&s->tim[i]), "clock", qdev_get_clock_out(
DEVICE(&s->clk), "timer-clock"));
sysbus_realize(sbd, &error_abort);
sysbus_mmio_map(sbd, 0, 0xb8001000);
sysbus_connect_irq(sbd, 1, 12); // Timer 1
/* IRQ for watchdogs */
sysbus_connect_irq(sbd, 5, npcm7xx_irq(s, 1));
/* GPIO that connects clk module with watchdog */
qdev_connect_gpio_out_named(DEVICE(&s->tim),
NPCM7XX_WATCHDOG_RESET_GPIO_OUT, 0,
qdev_get_gpio_in_named(DEVICE(&s->clk),
NPCM7XX_WATCHDOG_RESET_GPIO_IN, i));
The watchdog require npcm7xx clock ? For the timer2/3/4 with need a adustment with npcm7xx-timer ?
It's really complicated because npcm7xx use new method of implementation device (I can't make it work) and the old method with versation (only UART work).
With have only 1 address for timers on 0xb8001000 ?
Yes, I think that's right.
Regarding IRQs: I'm not familiar with QEMU's IRQ infrastructure, but you can see the interrupt numbers in the wiki.
Regarding clocks... I don't know if they're simulated in QEMU. Maybe you can ignore them entirely.
I have create 2 branch :
On NPCM7XX
branch (https://github.com/StidOfficial/qemu/tree/wpcm450-npcm7xx-base) :
(qemu) info mtree
address-space: memory
0000000000000000-ffffffffffffffff (prio 0, i/o): system
00000000b8000000-00000000b800001f (prio 0, i/o): serial
00000000b8001000-00000000b800101f (prio 0, i/o): serial
00000000f03fe000-00000000f03fffff (prio 0, i/o): a9mp-priv-container
00000000f03fe100-00000000f03fe1ff (prio 0, i/o): gic_cpu
00000000f03fe200-00000000f03fe21f (prio 0, i/o): a9gtimer shared
00000000f03fe600-00000000f03fe61f (prio 0, i/o): arm_mptimer_timer
00000000f03fe620-00000000f03fe63f (prio 0, i/o): arm_mptimer_timer
00000000f03ff000-00000000f03fffff (prio 0, i/o): gic_dist
address-space: I/O
0000000000000000-000000000000ffff (prio 0, i/o): io
address-space: cpu-memory-0
0000000000000000-ffffffffffffffff (prio 0, i/o): system
00000000b8000000-00000000b800001f (prio 0, i/o): serial
00000000b8001000-00000000b800101f (prio 0, i/o): serial
00000000f03fe000-00000000f03fffff (prio 0, i/o): a9mp-priv-container
00000000f03fe100-00000000f03fe1ff (prio 0, i/o): gic_cpu
00000000f03fe200-00000000f03fe21f (prio 0, i/o): a9gtimer shared
00000000f03fe600-00000000f03fe61f (prio 0, i/o): arm_mptimer_timer
00000000f03fe620-00000000f03fe63f (prio 0, i/o): arm_mptimer_timer
00000000f03ff000-00000000f03fffff (prio 0, i/o): gic_dist
(qemu) info roms
addr=0000000000000000 size=0x00001c mem=ram name="bootloader"
addr=0000000000010000 size=0x010000 mem=ram name="../../wpcm450/src/bare-metal/monitor.img"
(qemu) info qom-tree
/machine (idrac6-bmc-machine)
/peripheral (container)
/peripheral-anon (container)
/soc (nuvoton-wpcm450)
/a9mpcore (a9mpcore_priv)
/a9mp-priv-container[0] (memory-region)
/gic (arm_gic)
/gic_cpu[0] (memory-region)
/gic_cpu[1] (memory-region)
/gic_dist[0] (memory-region)
/unnamed-gpio-in[0] (irq)
/unnamed-gpio-in[10] (irq)
/unnamed-gpio-in[11] (irq)
/unnamed-gpio-in[12] (irq)
/unnamed-gpio-in[13] (irq)
/unnamed-gpio-in[14] (irq)
/unnamed-gpio-in[15] (irq)
/unnamed-gpio-in[16] (irq)
/unnamed-gpio-in[17] (irq)
/unnamed-gpio-in[18] (irq)
/unnamed-gpio-in[19] (irq)
/unnamed-gpio-in[1] (irq)
/unnamed-gpio-in[20] (irq)
/unnamed-gpio-in[21] (irq)
/unnamed-gpio-in[22] (irq)
/unnamed-gpio-in[23] (irq)
/unnamed-gpio-in[24] (irq)
/unnamed-gpio-in[25] (irq)
/unnamed-gpio-in[26] (irq)
/unnamed-gpio-in[27] (irq)
/unnamed-gpio-in[28] (irq)
/unnamed-gpio-in[29] (irq)
/unnamed-gpio-in[2] (irq)
/unnamed-gpio-in[30] (irq)
/unnamed-gpio-in[31] (irq)
/unnamed-gpio-in[32] (irq)
/unnamed-gpio-in[33] (irq)
/unnamed-gpio-in[34] (irq)
/unnamed-gpio-in[35] (irq)
/unnamed-gpio-in[36] (irq)
/unnamed-gpio-in[37] (irq)
/unnamed-gpio-in[38] (irq)
/unnamed-gpio-in[39] (irq)
/unnamed-gpio-in[3] (irq)
/unnamed-gpio-in[40] (irq)
/unnamed-gpio-in[41] (irq)
/unnamed-gpio-in[42] (irq)
/unnamed-gpio-in[43] (irq)
/unnamed-gpio-in[44] (irq)
/unnamed-gpio-in[45] (irq)
/unnamed-gpio-in[46] (irq)
/unnamed-gpio-in[47] (irq)
/unnamed-gpio-in[48] (irq)
/unnamed-gpio-in[49] (irq)
/unnamed-gpio-in[4] (irq)
/unnamed-gpio-in[50] (irq)
/unnamed-gpio-in[51] (irq)
/unnamed-gpio-in[52] (irq)
/unnamed-gpio-in[53] (irq)
/unnamed-gpio-in[54] (irq)
/unnamed-gpio-in[55] (irq)
/unnamed-gpio-in[56] (irq)
/unnamed-gpio-in[57] (irq)
/unnamed-gpio-in[58] (irq)
/unnamed-gpio-in[59] (irq)
/unnamed-gpio-in[5] (irq)
/unnamed-gpio-in[60] (irq)
/unnamed-gpio-in[61] (irq)
/unnamed-gpio-in[62] (irq)
/unnamed-gpio-in[63] (irq)
/unnamed-gpio-in[6] (irq)
/unnamed-gpio-in[7] (irq)
/unnamed-gpio-in[8] (irq)
/unnamed-gpio-in[9] (irq)
/gtimer (arm.cortex-a9-global-timer)
/a9gtimer per cpu[0] (memory-region)
/a9gtimer shared[0] (memory-region)
/mptimer (arm_mptimer)
/arm_mptimer_timer[0] (memory-region)
/arm_mptimer_timerblock[0] (memory-region)
/unnamed-gpio-in[0] (irq)
/unnamed-gpio-in[10] (irq)
/unnamed-gpio-in[11] (irq)
/unnamed-gpio-in[12] (irq)
/unnamed-gpio-in[13] (irq)
/unnamed-gpio-in[14] (irq)
/unnamed-gpio-in[15] (irq)
/unnamed-gpio-in[16] (irq)
/unnamed-gpio-in[17] (irq)
/unnamed-gpio-in[18] (irq)
/unnamed-gpio-in[19] (irq)
/unnamed-gpio-in[1] (irq)
/unnamed-gpio-in[20] (irq)
/unnamed-gpio-in[21] (irq)
/unnamed-gpio-in[22] (irq)
/unnamed-gpio-in[23] (irq)
/unnamed-gpio-in[24] (irq)
/unnamed-gpio-in[25] (irq)
/unnamed-gpio-in[26] (irq)
/unnamed-gpio-in[27] (irq)
/unnamed-gpio-in[28] (irq)
/unnamed-gpio-in[29] (irq)
/unnamed-gpio-in[2] (irq)
/unnamed-gpio-in[30] (irq)
/unnamed-gpio-in[31] (irq)
/unnamed-gpio-in[3] (irq)
/unnamed-gpio-in[4] (irq)
/unnamed-gpio-in[5] (irq)
/unnamed-gpio-in[6] (irq)
/unnamed-gpio-in[7] (irq)
/unnamed-gpio-in[8] (irq)
/unnamed-gpio-in[9] (irq)
/wdt (arm_mptimer)
/arm_mptimer_timer[0] (memory-region)
/arm_mptimer_timerblock[0] (memory-region)
/cpu[0] (arm926-arm-cpu)
/unnamed-gpio-in[0] (irq)
/unnamed-gpio-in[1] (irq)
/unnamed-gpio-in[2] (irq)
/unnamed-gpio-in[3] (irq)
/unattached (container)
/device[0] (serial-mm)
/serial (serial)
/serial[0] (memory-region)
/device[1] (serial-mm)
/serial (serial)
/serial[0] (memory-region)
/io[0] (memory-region)
/sysbus (System)
/system[0] (memory-region)
I can't set maximum irq's to 32 at the moment because GICState can only support 64 and more.
The UART0 doesn't work, but the addresses are correct so i think is a instructor error stop monitor.img execution :
00000000b8000000-00000000b800001f (prio 0, i/o): serial
00000000b8001000-00000000b800101f (prio 0, i/o): serial
I didn't look with gdb.
For versatile
branch (https://github.com/StidOfficial/qemu/tree/wpcm450-versatile-base) :
(qemu) info mtree
address-space: memory
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-000000000fffffff (prio 0, ram): wpcm450.ram
0000000010140000-0000000010140fff (prio 0, i/o): pl190
00000000b8000000-00000000b800001f (prio 0, i/o): serial
00000000b8000100-00000000b800011f (prio 0, i/o): serial
address-space: I/O
0000000000000000-000000000000ffff (prio 0, i/o): io
address-space: cpu-memory-0
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-000000000fffffff (prio 0, ram): wpcm450.ram
0000000010140000-0000000010140fff (prio 0, i/o): pl190
00000000b8000000-00000000b800001f (prio 0, i/o): serial
00000000b8000100-00000000b800011f (prio 0, i/o): serial
(qemu) info roms
addr=0000000000000000 size=0x00001c mem=ram name="bootloader"
addr=0000000000010000 size=0x010000 mem=ram name="../../wpcm450/src/bare-metal/monitor.img"
(qemu) info qom-tree
/machine (idrac6-bmc-machine)
/peripheral (container)
/peripheral-anon (container)
/soc (arm926-arm-cpu)
/unnamed-gpio-in[0] (irq)
/unnamed-gpio-in[1] (irq)
/unnamed-gpio-in[2] (irq)
/unnamed-gpio-in[3] (irq)
/unattached (container)
/device[0] (pl190)
/pl190[0] (memory-region)
/unnamed-gpio-in[0] (irq)
/unnamed-gpio-in[10] (irq)
/unnamed-gpio-in[11] (irq)
/unnamed-gpio-in[12] (irq)
/unnamed-gpio-in[13] (irq)
/unnamed-gpio-in[14] (irq)
/unnamed-gpio-in[15] (irq)
/unnamed-gpio-in[16] (irq)
/unnamed-gpio-in[17] (irq)
/unnamed-gpio-in[18] (irq)
/unnamed-gpio-in[19] (irq)
/unnamed-gpio-in[1] (irq)
/unnamed-gpio-in[20] (irq)
/unnamed-gpio-in[21] (irq)
/unnamed-gpio-in[22] (irq)
/unnamed-gpio-in[23] (irq)
/unnamed-gpio-in[24] (irq)
/unnamed-gpio-in[25] (irq)
/unnamed-gpio-in[26] (irq)
/unnamed-gpio-in[27] (irq)
/unnamed-gpio-in[28] (irq)
/unnamed-gpio-in[29] (irq)
/unnamed-gpio-in[2] (irq)
/unnamed-gpio-in[30] (irq)
/unnamed-gpio-in[31] (irq)
/unnamed-gpio-in[3] (irq)
/unnamed-gpio-in[4] (irq)
/unnamed-gpio-in[5] (irq)
/unnamed-gpio-in[6] (irq)
/unnamed-gpio-in[7] (irq)
/unnamed-gpio-in[8] (irq)
/unnamed-gpio-in[9] (irq)
/device[1] (serial-mm)
/serial (serial)
/serial[0] (memory-region)
/device[2] (serial-mm)
/serial (serial)
/serial[0] (memory-region)
/io[0] (memory-region)
/sysbus (System)
/system[0] (memory-region)
The UART0 work, but is difficult to implement the TIMER0 for wait_for_key
without create a custom timer device.
If anyone see what is wrong with NPCM7xx branch.
On
NPCM7XX
branch (https://github.com/StidOfficial/qemu/tree/wpcm450-npcm7xx-base) :(qemu) info mtree address-space: memory 0000000000000000-ffffffffffffffff (prio 0, i/o): system 00000000b8000000-00000000b800001f (prio 0, i/o): serial 00000000b8001000-00000000b800101f (prio 0, i/o): serial
The base address of the second UART should be 0xb8000100, not 0xb8001000.
00000000f03fe000-00000000f03fffff (prio 0, i/o): a9mp-priv-container 00000000f03fe100-00000000f03fe1ff (prio 0, i/o): gic_cpu 00000000f03fe200-00000000f03fe21f (prio 0, i/o): a9gtimer shared 00000000f03fe600-00000000f03fe61f (prio 0, i/o): arm_mptimer_timer 00000000f03fe620-00000000f03fe63f (prio 0, i/o): arm_mptimer_timer 00000000f03ff000-00000000f03fffff (prio 0, i/o): gic_dist
This stuff looks unnecessary.
It looks like a mapping for RAM is missing. The versatile branch has this line:
0000000000000000-000000000fffffff (prio 0, ram): wpcm450.ram
(although 00000000-3fffffff should be (more than) enough)
I can't set maximum irq's to 32 at the moment because GICState can only support 64 and more.
Don't worry. In the long term, GIC is the wrong interrupt controller for WPCM450 anyway.
The UART0 doesn't work, but the addresses are correct so i think is a instructor error stop monitor.img execution :
QEMU has some options for instruction tracing, such as -d in_asm
. Maybe they'll help in finding the culprit.
For
versatile
branch (https://github.com/StidOfficial/qemu/tree/wpcm450-versatile-base) :(qemu) info mtree address-space: memory 0000000000000000-ffffffffffffffff (prio 0, i/o): system 0000000000000000-000000000fffffff (prio 0, ram): wpcm450.ram 0000000010140000-0000000010140fff (prio 0, i/o): pl190
Again, the wrong interrupt controller
00000000b8000000-00000000b800001f (prio 0, i/o): serial 00000000b8000100-00000000b800011f (prio 0, i/o): serial
But the address of the second UART is right.
The base address of the second UART should be 0xb8000100, not 0xb8001000.
Now is fix
This stuff looks unnecessary.
I regard for NPCM7XX base. But for versatile, i remove the pl190 VIC. Now we have :
(qemu) info mtree
address-space: memory
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-000000000fffffff (prio 0, ram): wpcm450.ram
00000000b8000000-00000000b800001f (prio 0, i/o): serial
00000000b8000100-00000000b800011f (prio 0, i/o): serial
address-space: I/O
0000000000000000-000000000000ffff (prio 0, i/o): io
address-space: cpu-memory-0
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-000000000fffffff (prio 0, ram): wpcm450.ram
00000000b8000000-00000000b800001f (prio 0, i/o): serial
00000000b8000100-00000000b800011f (prio 0, i/o): serial
It looks like a mapping for RAM is missing. The versatile branch has this line:
0000000000000000-000000000fffffff (prio 0, ram): wpcm450.ram
Yes i have disable the DRAM, i remove the ifdef and now :
(qemu) info mtree
address-space: memory
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-000000000fffffff (prio 0, ram): ram
00000000b8000000-00000000b800001f (prio 0, i/o): serial
00000000b8000100-00000000b800011f (prio 0, i/o): serial
address-space: I/O
0000000000000000-000000000000ffff (prio 0, i/o): io
address-space: cpu-memory-0
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-000000000fffffff (prio 0, ram): ram
00000000b8000000-00000000b800001f (prio 0, i/o): serial
00000000b8000100-00000000b800011f (prio 0, i/o): serial
(although 00000000-3fffffff should be (more than) enough)
On my iDRAC6 i remember (i not sure), i got 264 MiB of RAM, you have 1024 MiB on your iDRAC ?
Now NPCM7XX branch work for UART. You can compile for test and use like this :
./qemu-system-arm -M idrac6-bmc -kernel ../../wpcm450/src/bare-metal/monitor.img
I going to try to implement the npcm7xx_timer and ignore IRQ's interraction. Do you known if we have a standard IC, if we have all necessary information in your wiki ? Do you known if is possible with this state U-boot or not and what is minimal requirement ? And what is the minimum requirement for kernel ? Do you think if is possible to use you bare metal work to implement step by step Watchdor, I2C, IC, ... (I don't known the priority) with QEMU ?
(although 00000000-3fffffff should be (more than) enough)
On my iDRAC6 i remember (i not sure), i got 264 MiB of RAM, you have 1024 MiB on your iDRAC ?
My Supermicro boards have 128 MiB; I haven't checked my Dell board. However, the window in physical address space where RAM can be accessed is larger. The upper bits, that are not used for addressing the RAM, are ignored and the RAM content looks like it repeats in physical address space:
> ww 2000 1 2 3 4 5 6 7 8 # write a test pattern into RAM
> rw 2000 16 # read it back
00002000: 00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000008
00002020: 7273752f 6962732f 690a0a6e 205b2066 53502422 5d202231 6874203b 090a6e65
> rw 08002000 16 # same content at 128 MiB
08002000: 00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000008
08002020: 7273752f 6962732f 690a0a6e 205b2066 53502422 5d202231 6874203b 090a6e65
> rw 0c002000 16 # not at 192 MiB
0c002000: 000220a4 00000005 81020000 00408000 00001800 00000000 08004000 00404001
0c002020: 28000000 50000020 00010002 04800200 00002000 0400000c 82000940 00820000
> rw 10002000 16 # same at 256 MiB
10002000: 00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000008
10002020: 7273752f 6962732f 690a0a6e 205b2066 53502422 5d202231 6874203b 090a6e65
> rw 20002000 16 # oops, reading here causes a crash
20002000: Press any key to avoid running the default boot script
Loading Linux...
Two things to note here:
At 0, there is a small block of chip-internal RAM (0x2000 bytes), which shadows the DRAM. This is why values written to 0x00000000 would not be mirrored at 0x08000000.
Up to (and excluding) address 0x20000000, DRAM repeats, so that's how large the DRAM access window is.
I going to try to implement the npcm7xx_timer and ignore IRQ's interraction.
Good. That should be enough to make the timeout logic in monitor.c work.
Do you known if we have a standard IC, if we have all necessary information in your wiki ?
IC meaning interrupt controller? In that case, no, it's not a standard part, it's specific to Winbond/Nuvoton. The wiki page (https://github.com/neuschaefer/wpcm450/wiki/Interrupts) lists the registers and has a few references that can hopefully help you understand the interrupt controller.
If you have questions about any hardware (like the interrupt controller, for example), please ask, ideally in a new github issue for each specific hardware block.
Do you known if is possible with this state U-boot or not and what is minimal requirement ?
Your question is missing a verb. To do what with U-Boot?
And what is the minimul requirement for kernel ?
The kernel port as it was merged in 5.13-rc1 requires the interrupt controller, timer/watchdog, and UART.
Do you think if is possible to use you bare metal work to implement step by step Watchdor, I2C, IC, ... (I don't known the priority) with QEMU ?
My monitor program can probably help a little bit in implementing/testing the various parts, but please note that it doesn't have a lot of drivers in it. The various kernels (ATEN's, AMI's, Dell's, mainline, mine) have more drivers.
My Supermicro boards have 128 MiB; I haven't checked my Dell board. However, the window in physical address space where RAM can be accessed is larger. The upper bits, that are not used for addressing the RAM, are ignored and the RAM content looks like it repeats in physical address space:
That the actual mapping i have made on QEMU :
(qemu) info mtree
address-space: memory
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-0000000000001fff (prio 0, ram): ram0
0000000000002000-0000000008001fff (prio 0, ram): dram0
0000000008002000-0000000010001fff (prio 0, ram): alias dram1 @dram0 0000000000000000-0000000007ffffff
0000000010002000-0000000018001fff (prio 0, ram): alias dram2 @dram0 0000000000000000-0000000007ffffff
0000000018002000-0000000020001fff (prio 0, ram): alias dram3 @dram0 0000000000000000-0000000007ffffff
00000000b0000200-00000000b00011ff (prio 0, i/o): npcm7xx-clk
00000000b8000000-00000000b800001f (prio 0, i/o): serial
00000000b8000100-00000000b800011f (prio 0, i/o): serial
00000000b8001000-00000000b8001fff (prio 0, i/o): npcm7xx-timer
00000000b8001004-00000000b8002003 (prio 0, i/o): npcm7xx-timer
00000000b8001020-00000000b800201f (prio 0, i/o): npcm7xx-timer
00000000b8001024-00000000b8002023 (prio 0, i/o): npcm7xx-timer
00000000b8001040-00000000b800203f (prio 0, i/o): npcm7xx-timer
00000000c6000000-00000000c60003ff (prio 0, ram): ram1
address-space: I/O
0000000000000000-000000000000ffff (prio 0, i/o): io
address-space: cpu-memory-0
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-0000000000001fff (prio 0, ram): ram0
0000000000002000-0000000008001fff (prio 0, ram): dram0
0000000008002000-0000000010001fff (prio 0, ram): alias dram1 @dram0 0000000000000000-0000000007ffffff
0000000010002000-0000000018001fff (prio 0, ram): alias dram2 @dram0 0000000000000000-0000000007ffffff
0000000018002000-0000000020001fff (prio 0, ram): alias dram3 @dram0 0000000000000000-0000000007ffffff
00000000b0000200-00000000b00011ff (prio 0, i/o): npcm7xx-clk
00000000b8000000-00000000b800001f (prio 0, i/o): serial
00000000b8000100-00000000b800011f (prio 0, i/o): serial
00000000b8001000-00000000b8001fff (prio 0, i/o): npcm7xx-timer
00000000b8001004-00000000b8002003 (prio 0, i/o): npcm7xx-timer
00000000b8001020-00000000b800201f (prio 0, i/o): npcm7xx-timer
00000000b8001024-00000000b8002023 (prio 0, i/o): npcm7xx-timer
00000000b8001040-00000000b800203f (prio 0, i/o): npcm7xx-timer
00000000c6000000-00000000c60003ff (prio 0, ram): ram1
memory-region: dram0
0000000000002000-0000000008001fff (prio 0, ram): dram0
I have create this table, he is similar to info mtree
Physical address | End address | Size | Name | Type | Description |
---|---|---|---|---|---|
0x00000000 | 0x0001ffff | 0x2000 (8 KiB) | RAM0 | Internal RAM0 | |
0x00002000 | 0x08001fff | 0x8000000 (128 MiB) | DRAM0 | DRAM0 | |
0x08002000 | 0x10001fff | 0x8000000 (128 MiB) | DRAM1 | DRAM0 alias Symbolic link to 0x00002000 (Is mirrored from 0x00002000 if global memory is equal to 128 MiB) | |
0x10002000 | 0x18001fff | 0x8000000 (128 MiB) | DRAM2 | DRAM0 alias Symbolic link to 0x00002000 (Is mirrored from 0x00002000 if global memory is equal to 128 MiB) | |
0x18002000 | 0x20001fff | 0x8000000 (128 MiB) | DRAM3 | DRAM0 alias Symbolic link to 0x00002000 (Is mirrored from 0x00002000 if global memory is equal to 128 MiB) | |
0xc6000000 | 0xc60003ff | 0x400 (1024 B) | RAM1 | Internal RAM1 |
Now i can reproduce your commands :
Press any key to avoid running the default boot script
_bootscript
Welcome to lolmon
> ww 2000 1 2 3 4 5 6 7 8
> rw 2000 16
00002000: 00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000008
00002020: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> rw 08002000 16
08002000: 00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000008
08002020: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> rw 0c002000 16
0c002000: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0c002020: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> rw 10002000 16
10002000: 00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000008
10002020: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> rw 20002000 16
20002000:
IC meaning interrupt controller? In that case, no, it's not a standard part, it's specific to Winbond/Nuvoton. The wiki page (https://github.com/neuschaefer/wpcm450/wiki/Interrupts) lists the registers and has a few references that can hopefully help you understand the interrupt controller. If you have questions about any hardware (like the interrupt controller, for example), please ask, ideally in a new github issue for each specific hardware block.
Yes, i mean Iterrupt Controller (excuse me for my weird english). Ok thanks
Your question is missing a verb. To do what with U-Boot?
I want to test u-boot with QEMU and i want to known what is the mimimum requirements (UART, Timer, ...) for compile and test it ?
(qemu) info mtree address-space: memory 0000000000000000-ffffffffffffffff (prio 0, i/o): system 0000000000000000-0000000000001fff (prio 0, ram): ram0 0000000000002000-0000000008001fff (prio 0, ram): dram0 0000000008002000-0000000010001fff (prio 0, ram): alias dram1 @dram0 0000000000000000-0000000007ffffff 0000000010002000-0000000018001fff (prio 0, ram): alias dram2 @dram0 0000000000000000-0000000007ffffff 0000000018002000-0000000020001fff (prio 0, ram): alias dram3 @dram0 0000000000000000-0000000007ffffff
Nice approach.
I'd argue that each DRAM mirror probably starts at a round address (00000000, 08000000, etc.), and that part of the first mirror is simply shadowed by the internal RAM; but the way you modeled it, it does seem to create (mostly) the correct behavior, so it's probably fine.
The part from 20000000 to 20001fff is wrong. Everything from 20000000 onward causes an error.
00000000b0000200-00000000b00011ff (prio 0, i/o): npcm7xx-clk
This overlaps with the memory controller (@ b0001000). Also, I haven't checked how similar and compatible the clock controllers of WPCM450 and NPCM7xx are. They might have incompatible register layouts.
00000000b8000000-00000000b800001f (prio 0, i/o): serial 00000000b8000100-00000000b800011f (prio 0, i/o): serial
Looks good!
00000000b8001000-00000000b8001fff (prio 0, i/o): npcm7xx-timer 00000000b8001004-00000000b8002003 (prio 0, i/o): npcm7xx-timer 00000000b8001020-00000000b800201f (prio 0, i/o): npcm7xx-timer 00000000b8001024-00000000b8002023 (prio 0, i/o): npcm7xx-timer 00000000b8001040-00000000b800203f (prio 0, i/o): npcm7xx-timer
Why does npcm7xx-timer have multiple ranges?
Now i can reproduice your behavior : [...]
rw 08002000 16 08002000: 00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000008
Great!
I want to test u-boot with QEMU and i want to known what is the mimimum requirements (UART, Timer, ...) for compile and test it ?
First of all, you have to select a version of U-Boot, because the upstream version does not support WPCM450. There are at least two versions provided by firmware vendors:
Both of these probably require a rather old toolchain (GCC, binutils, etc.).
There is currently no modern version of U-Boot for WPCM450.
I'd argue that each DRAM mirror probably starts at a round address (00000000, 08000000, etc.), and that part of the first mirror is simply shadowed by the internal RAM; but the way you modeled it, it does seem to create (mostly) the correct behavior, so it's probably fine. The part from 20000000 to 20001fff is wrong. Everything from 20000000 onward causes an error.
Do you mean like below. It's means the RAM0 is never used, everything use directly DRAM0 ?
address-space: memory
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-0000000007ffffff (prio 0, ram): dram0
0000000000000000-0000000000001fff (prio 0, ram): ram0
0000000008000000-000000000fffffff (prio 0, ram): alias dram1 @dram0 0000000000000000-0000000007ffffff
0000000010000000-0000000017ffffff (prio 0, ram): alias dram2 @dram0 0000000000000000-0000000007ffffff
0000000018000000-000000001fffffff (prio 0, ram): alias dram3 @dram0 0000000000000000-0000000007ffffff
00000000b0000200-00000000b00011ff (prio 0, i/o): npcm7xx-clk
00000000b8000000-00000000b800001f (prio 0, i/o): serial
00000000b8000100-00000000b800011f (prio 0, i/o): serial
00000000c6000000-00000000c60003ff (prio 0, ram): ram1
This overlaps with the memory controller (@ b0001000). Also, I haven't checked how similar and compatible the clock controllers of WPCM450 and NPCM7xx are. They might have incompatible register layouts.
If i have good understand, if (!wait_for_key(1000000)) {
, us
argument equal to microsecondes (µs) so he wait 1 seconde for key press. I have test with multiply this by 10 (10 secondes), i have calcule and he wait 10~ (with gnome-clocks). And the rst
command work so i think at least for monitor the clock and timer looks good.
That the actual memory mapping :
address-space: memory
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-0000000007ffffff (prio 0, ram): dram0
0000000000000000-0000000000001fff (prio 0, ram): ram0
0000000008000000-000000000fffffff (prio 0, ram): alias dram1 @dram0 0000000000000000-0000000007ffffff
0000000010000000-0000000017ffffff (prio 0, ram): alias dram2 @dram0 0000000000000000-0000000007ffffff
0000000018000000-000000001fffffff (prio 0, ram): alias dram3 @dram0 0000000000000000-0000000007ffffff
00000000b0000200-00000000b00011ff (prio 0, i/o): npcm7xx-clk
00000000b8000000-00000000b800001f (prio 0, i/o): serial
00000000b8000100-00000000b800011f (prio 0, i/o): serial
00000000b8001000-00000000b8001fff (prio 0, i/o): npcm7xx-timer
00000000c6000000-00000000c60003ff (prio 0, ram): ram1
First of all, you have to select a version of U-Boot, because the upstream version does not support WPCM450. There are at least two versions provided by firmware vendors: - AMI (https://github.com/neuschaefer/u-boot/tree/vendor/wpcm450-ami) - Dell (https://github.com/neuschaefer/u-boot/tree/vendor/dell-idrac6-1.70) Both of these probably require a rather old toolchain (GCC, binutils, etc.). There is currently no modern version of U-Boot for WPCM450.
Ok i going to try first with u-boot. I use currently use the cross compile arm-none-eabi-
given with fedora. I have also the cross compiler given by dell for irac6 if is needed.
Do you mean like below. It's means the RAM0 is never used, everything for inside DRAM0 ?
address-space: memory 0000000000000000-ffffffffffffffff (prio 0, i/o): system 0000000000000000-0000000007ffffff (prio 0, ram): dram0 0000000000000000-0000000000001fff (prio 0, ram): ram0 0000000008000000-000000000fffffff (prio 0, ram): alias dram1 @dram0 0000000000000000-0000000007ffffff 0000000010000000-0000000017ffffff (prio 0, ram): alias dram2 @dram0 0000000000000000-0000000007ffffff 0000000018000000-000000001fffffff (prio 0, ram): alias dram3 @dram0 0000000000000000-0000000007ffffff
This looks good, but I'm not sure how QEMU handles the overlap. The desired result is that ram0 is used in the overlapping area. I guess you can influence which memory is preferred by changing the priority ("prio" value).
If i have good understand,
if (!wait_for_key(1000000)) {
us equal to microsecondes (µs) so he wait 1 seconde for key press.
Yes, the parameter is in microseconds.
I have test with multiply this by 10 (10 secondes), i have calcule and he wait 10~ (with gnome-clocks). And the
rst
command work so i think at least for monitor the clock and timer looks good.
Very good!
I have disable lot of code (SPI, GPIO and SMC) but we hare close for u-boot.
U-Boot 1.2.0-gbacd4830-dirty (Sep 8 2021 - 18:22:29) Avocent (1.13.7) Whoville
Board: WPCM450_00
DRAM: 128 MB
Flash: 0 kB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: No ethernet found.
Hit any key to stop autoboot: 0
[uboot_wpcm450]#
@neuschaefer Do you check https://datasheetspdf.com/pdf-file/1134405/nuvoton/NUC960ADN/1 beacause there are very similar registers, base addresses, ... ?
@StidOfficial thanks for the link! :)
It would be interesting to have WPCM450 system emulation in QEMU. Some of the peripherals of NPCM7xx can probably be reused.