Opened 7 years ago
Closed 2 years ago
#14095 closed bug (invalid)
ARM RPI2: Device mapping commented out
Reported by: | robg2 | Owned by: | nobody |
---|---|---|---|
Priority: | normal | Milestone: | Unscheduled |
Component: | System/Boot Loader/uboot | Version: | R1/Development |
Keywords: | ARM RPI2 | Cc: | |
Blocked By: | Blocking: | ||
Platform: | arm |
Description
I've been looking into the issue with the 'MMU hang' when running Haiku on an emulated Raspberry Pi2 via QEMU.
I believe the problem is that the device memory mapping has been commented out at https://git.haiku-os.org/haiku/tree/src/system/boot/arch/arm/arch_mmu.cpp#n91
The MMU is enabled as the last act of init_page_directory(), and control returns to mmu_init(), line 743. At line 748, a TRACE message is attempted, which will write to the UART. Without the device memory at 0x3f000000 mapped, this will fail.
This quick hack to uncomment the code and #define some DEVICE_* parameters let me get farther:
diff --git a/src/system/boot/arch/arm/arch_mmu.cpp b/src/system/boot/arch/arm/arch_mmu.cpp index d4c5450ed21..e4f77c3a5fb 100644 --- a/src/system/boot/arch/arm/arch_mmu.cpp +++ b/src/system/boot/arch/arm/arch_mmu.cpp @@ -87,15 +87,17 @@ struct memblock { #warning TODO: Plot pref. base from fdt! +#define DEVICE_BASE 0x3f000000 +#define DEVICE_SIZE 0x01000000 static struct memblock LOADER_MEMORYMAP[] = { -/* + { "devices", DEVICE_BASE, DEVICE_BASE + DEVICE_SIZE - 1, ARM_MMU_L2_FLAG_B, }, -*/ + { "RAM_kernel", // 8MB space for kernel, drivers etc KERNEL_LOAD_BASE,
With this hack I can get a screen on the serial port that looks like this:
Welcome to the Haiku Boot Loader Copyright 2004-2014 Haiku, Inc. Select boot volume (Current: None) Select safe mode options Select debug options Reboot Continue booting
The qemu command line I am using is
qemu-system-arm -M raspi2 -kernel haiku_loader.ub -initrd haiku-floppyboot.tgz.ub -dtb rpi2.dtb -serial stdio -m 2G
I suppose the proper fix is to read device mapping info from the device tree. It looks like the code may be in the middle of a transition from pre-device-tree to device-tree. I'm not sure.
Attachments (2)
Change History (11)
comment:1 by , 7 years ago
comment:2 by , 7 years ago
Might the work in https://github.com/jarekpelczar/haiku-jarek/commits/master be relevant? Either regarding the issue directly (though it looks like that work is all about aarch64) or regarding the device tree?
comment:3 by , 6 years ago
I ran over (slowly) what happens.
The first attempt to print to the serial port after init_page_directory() in mmu_allocate() results in the exception handler getting triggered.
Attaching a gdb trace.
fdt_get_range_offset: range offset: 0x0 fdt_get_device_reg_byname: /axi/mbox found @ 0x3f00b880 Found boot tgz from FDT @ 0x08000000, 1601071 bytes argc = 0 os: 2 gd @ 0x00000000 FDT @ 0x08187000: fdt_totalsize: 36654 fdt_off_dt_struct: 56 fdt_off_dt_strings: 7780 fdt_off_mem_rsvmap: 40 fdt_version: 17 fdt_last_comp_version: 16 fdt_boot_cpuid_phys: 3840 fdt_size_dt_strings: 615 fdt_size_dt_struct: 7724 fdtSize: 0x8f2e mmu_init checking for memory... 0: base = 0,size = 2080374784 total physical memory = 1984MB init_page_directory mmu_map_identity: [ 1000000 - 1053000] get_next_page_table, sNextPageTableAddress 0x1104000, sPageTableRegionEnd 0x1300000, type 0x1 mmu_map_identity: [ 1100000 - 1300000] get_next_page_table, sNextPageTableAddress 0x1104400, sPageTableRegionEnd 0x1300000, type 0x1 get_next_page_table, sNextPageTableAddress 0x1104800, sPageTableRegionEnd 0x1300000, type 0x1 BLOCK: RAM_kernel START: 80000000 END 807fffff mmu_map_identity: [ 80000000 - 80800000] get_next_page_table, sNextPageTableAddress 0x1104c00, sPageTableRegionEnd 0x1300000, type 0x1 get_next_page_table, sNextPageTableAddress 0x1105000, sPageTableRegionEnd 0x1300000, type 0x1 get_next_page_table, sNextPageTableAddress 0x1105400, sPageTableRegionEnd 0x1300000, type 0x1 get_next_page_table, sNextPageTableAddress 0x1105800, sPageTableRegionEnd 0x1300000, type 0x1 get_next_page_table, sNextPageTableAddress 0x1105c00, sPageTableRegionEnd 0x1300000, type 0x1 get_next_page_table, sNextPageTableAddress 0x1106000, sPageTableRegionEnd 0x1300000, type 0x1 get_next_page_table, sNextPageTableAddress 0x1106400, sPageTableRegionEnd 0x1300000, type 0x1 get_next_page_table, sNextPageTableAddress 0x1106800, sPageTableRegionEnd 0x1300000, type 0x1
I never see the reported mmu_allocate: requested vaddr: 0x00000000, next free vaddr: 0x80800000, size: 16384
.
comment:4 by , 6 years ago
Obviously, I spent a while figuring out what you already did @robg2 :-)
So, we need to parse the DTB to determine the base of the hardware devices.
On broadcom (rpi) and TI (beaglebone) devices it is "simple-bus".
- The broadcom dts specifies where simple-bus is.
- The TI dts specifies simple-bus, but doesn't give a base.
We might need setup memory areas for each physical device in the dtb vs assuming they will all be present in a preserved range :-|
comment:5 by , 6 years ago
Yes, mapping each device separately makes sense and saves on address space.
We will need an FDT bus (similar to the PCI one) providing access to device information (base address, size, etc). Then it is up to each device driver to map this into memory (as is the case with PCI already - we don't map the whole PCI space to memory as a big block). Note that this also provides some protection between drivers - you write to your device page, and normally you don't accidentally access registers from neighbor devices.
For the debug serial port case, it is ok to have a setting in the kernel settings file as we need this setup much earlier than everything else. In fact there is already a setting for x86 (it sets an IO port and not a memory address, but the idea is the same). This is needed anyways because there can be multiple serial ports, and the kernel wouldn't know which one to use (and they may not all be reachable by the user, for example connected internally to a GPS receiver or IR port or whatnot).
So:
- For the serial port, just use the existing serial_debug_port setting (accept an address here) and look for a typical 16c550 serial controller at that address.
- For all other devices, before accessing them, we need to find where they are in the FDT.
- We may need the FDT for other purposes early in the kernel, for example to find where the RAM is (I'm sure we'll need this at some point before the bus manager can be set up). But we can live with some hardcoded things as a first step here.
comment:6 by , 6 years ago
A first iteration of FDT-based mapping of peripherals was pushed in hrev52175.
hrev52175 is limited to functioning under the following situations:
- /axi is where the peripherals are
- /axi contains the register offsets for "all the peripherals"
- The peripheral space is 0x01000000 long
This "fixes" Haiku under qemu emulating the raspberry pi, and should fix Haiku booting on the raspberry pi.
I need to write a lot of FDT support code to improve this and make it more generic:
- We need a function to "find" compatible devices in the FDT tree.
- We need fdt_get_device_size to get the size of the FDT device register space.
After the above is complete, we need to "find" simple-bus and map *each* peripheral (vs the overall "peripheral space" since all of the peripherals existing in the same space isn't guaranteed) under it.
I'd avoid making any changes to FDT support code however until we decide if https://review.haiku-os.org/c/haiku/+/440 is going in the right direction. I need feedback from mmu_man on that one.
comment:7 by , 5 years ago
Component: | System/Boot Loader → System/Boot Loader/uboot |
---|
comment:8 by , 2 years ago
This one seems to be related to the u-boot loader which has been removed by Waddlesplash so I guess this ticket can be closed.
Yes, the migration to device tree is in progress. And you are right, instead of hardcoding things in the sourcecode, the whole memory map should be built from the device tree.