It is platform name, not architecture name, architecture name is “riscv64”.
Ok.
“Superfluous text to meet the minimum requirement of 12 characters.”
What’s your qemu command for booting this?
/boot/data/packages/haikuports/app-emulation/qemu/work-6.0.0/sources/qemu-6.0.0/build/build/install/bin/qemu-system-riscv64 \
-machine virt \
-global virtio-mmio.force-legacy=false \
-m 256M \
-bios "/Haiku/data/packages/haiku/generated.riscv64/objects/haiku/riscv64/release/system/boot/riscv/haiku_loader.riscv" \
-serial stdio \
-parallel none \
-monitor none \
-device ramfb \
-device virtio-keyboard-device,bus=virtio-mmio-bus.1 \
-device virtio-tablet-device,bus=virtio-mmio-bus.0 \
-device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.2 \
-device virtio-net-device,netdev=usernet,bus=virtio-mmio-bus.3 \
-drive file="/Haiku/data/packages/haiku/generated.riscv64/haiku-minimum2.image",if=none,format=raw,id=x0 \
-netdev user,id=usernet
ah. ok. That makes sense. So you’re running Haiku in machine mode directly from the haiku_loader’s riscv64 bootloader
Network operation is confirmed in Qemu, but it is slower than in TinyEMU (TinyEMU: 1.2 MiB/s, Qemu: 600 KiB/s). Similar to TinyEMU it require replacing “/etc/resolv.conf” with “/boot/system/settings/network/resolv.conf” in Slirp library (used to get DNS IP address).
virtio_net
driver don’t correctly handle Virtio header packet size and need to be fixed. It assume fixed Virtio packet header size instead of reading size in header. Qemu and TinyEMU use different Virtio header size.
Initial PCI bus support is working. It was easier than I expected, most of existing PCI bus driver code can be reused. On FDT platform PCI bus is no longer a root bus, it is attached to PCI FDT node. Some initialization order rework is needed because PCI bus registers can be accesses only after root PCI bus node will be attached to FDT node. I also implemented initial MMIO space allocation, I didn’t find MMIO allocation code in existing PCI bus driver.
Currently IRQ allocation is not implemented so XHCI driver fails:
usb xhci: xhci init module
usb xhci: searching devices
module: Search for bus_managers/pci/x86/v1 failed.
usb xhci: failed to get pci x86 module
usb xhci: found device at PCI:0:1:0
usb xhci -1: constructing new XHCI host controller driver
usb xhci -1: map registers 400000000, size: 16384
usb xhci -1: mapped registers: 0x0000000080e68000
usb xhci -1: operational register offset: 64
usb xhci -1: runtime register offset: 4096
usb xhci -1: doorbell register offset: 8192
usb xhci -1: interface version: 0x0100
usb xhci -1: structural parameters: 1:0x08001040 2:0x0000000f 3:0x00000000
usb xhci -1: capability parameters: 0x00080001
usb xhci -1: eecp register: 0x00000020
usb xhci -1: eecp register: 0x00000030
usb xhci -1: ControllerReset() cmd: 0x0 sts: 0x1
arch_thread_init_kthread_stack(0x00000000cdda9a40(xhci event thread))
arch_thread_init_kthread_stack(0x00000000cdda94c0(xhci finish thread))
usb xhci: device PCI:0:1:0 was assigned an invalid IRQ
usb xhci: bus failed init check
usb xhci -1: tear down XHCI host controller driver
usb xhci: no devices found
usb xhci: xhci uninit module
USB XHCI controller (USB 3) is working. Definitely useful on real hardware.
really inspiring to see all progress
After some fighting with PCI interrupt handling (NVMe disk driver seems expecting MSI-X interrupt handling that is not supported yet for riscv64. Also MSI/MSI-X Haiku driver API is currently x86-specific), NVMe disk is working. HiFive Unmatched has NVMe SSD disk slot.
Trying to run emulated PCI ATI Rage 128 Pro graphics card that is supported by both Qemu (-device ati-vga
) and Haiku. Crashes for now. I see some suspicious places that seems to be not compatible with 64 bits.
do the old rage ati cards support 64 bit adress spaces ??
Support of 64 bit addresses by graphics card is not required, 32 bit physical addresses can be allocated by PCI resource allocator.
ATI Rage 128 graphics card is working. Adding Rage128_SetDPMSMode(B_DPMS_ON);
call was required because monitor is turned off by default. Resolution and bits per pixel change is working. I disabled ramfb
driver so no graphics output is produced until app_server
is started (on real hardware something similar will be likely occur because u-boot likely don’t have PCI graphics card drivers). Also I fixed a bug when kernel crash if no kernel framebuffer is provided.
I tried to keep ramfb driver and that caused 2 Qemu windows to open: one is ramfb with kernel framebuffer and second is ATI Rage 128 Pro with app_server
.
there have been issues with audio drivers and adress space, i mentioned it because it’s one of those issues that have been randomly popping up since the 64b changes were made years ago
EFI boot and SBI timer is working. Page table initialization code was moved from kernel to haiku_loader.efi
. u-boot messed interrupt controller (PLIC) and PCI bus so some adjustments was needed. Also u-boot seems to provide wrong memory map: bootServicesData block is not available for memory allocation, it cause physical memory access exception. Provided FDT table seems fine.
u-boot don’t provide GOP framebuffer because Qemu-compatible driver is not implemented. It have simple-framebuffer
driver that is supported by TinyEMU, but not Qemu. I currently use PCI ATI Rage 128 Pro video card (-device ati-vga
).
haiku_loader.riscv
is still working, kernel can work with 2 platforms: riscv and sbi/efi.
@kallisti5 may be interested.
OpenSBI v0.9
____ _____ ____ _____
/ __ \ / ____| _ \_ _|
| | | |_ __ ___ _ __ | (___ | |_) || |
| | | | '_ \ / _ \ '_ \ \___ \| _ < | |
| |__| | |_) | __/ | | |____) | |_) || |_
\____/| .__/ \___|_| |_|_____/|____/_____|
| |
|_|
Platform Name : riscv-virtio,qemu
Platform Features : timer,mfdeleg
Platform HART Count : 1
Firmware Base : 0x80000000
Firmware Size : 100 KB
Runtime SBI Version : 0.2
Domain0 Name : root
Domain0 Boot HART : 0
Domain0 HARTs : 0*
Domain0 Region00 : 0x0000000080000000-0x000000008001ffff ()
Domain0 Region01 : 0x0000000000000000-0xffffffffffffffff (R,W,X)
Domain0 Next Address : 0x0000000080200000
Domain0 Next Arg1 : 0x000000009f000000
Domain0 Next Mode : S-mode
Domain0 SysReset : yes
Boot HART ID : 0
Boot HART Domain : root
Boot HART ISA : rv64imafdcsu
Boot HART Features : scounteren,mcounteren,time
Boot HART PMP Count : 16
Boot HART PMP Granularity : 4
Boot HART PMP Address Bits: 54
Boot HART MHPM Count : 0
Boot HART MHPM Count : 0
Boot HART MIDELEG : 0x0000000000000222
Boot HART MEDELEG : 0x000000000000b109
U-Boot 2021.04-00604-ga1e95e3805 (Apr 09 2021 - 18:20:46 -0500)
CPU: rv64imafdcsu
Model: riscv-virtio,qemu
DRAM: 512 MiB
In: uart@10000000
Out: uart@10000000
Err: uart@10000000
Net: eth0: virtio-net#3
Hit any key to stop autoboot: 0
Device 0: QEMU VirtIO Block Device
Type: Hard Disk
Capacity: 2.8 MB = 0.0 GB (5760 x 512)
... is now current device
Scanning virtio 0:1...
** Unable to read file / **
Failed to load '/'
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
Scanning disk virtio-blk#4...
Scanning disk virtio-blk#5...
** Unrecognized filesystem type **
Found 3 disks
No EFI system partition
BootOrder not defined
EFI boot manager: Cannot load any image
Found EFI removable media binary efi/boot/bootriscv64.efi
449079 bytes read in 2 ms (214.1 MiB/s)
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
Booting /efi\boot\bootriscv64.efi
System provided memory map:
phys: 0x80000000, virt: 0x80000000, size: 0x20000, bootServicesData, attrs: 0x8
phys: 0x80020000, virt: 0x80020000, size: 0x7edb000, conventionalMemory, attrs: 0x8
phys: 0x87efb000, virt: 0x87efb000, size: 0xa000, ACPIReclaimMemory, attrs: 0x8
phys: 0x87f05000, virt: 0x87f05000, size: 0x141f2000, conventionalMemory, attrs: 0x8
phys: 0x9c0f7000, virt: 0x9c0f7000, size: 0x25db000, loaderData, attrs: 0x8
phys: 0x9e6d2000, virt: 0x9e6d2000, size: 0x55000, loaderCode, attrs: 0x8
phys: 0x9e727000, virt: 0x9e727000, size: 0x7000, reservedMemoryType, attrs: 0x8
phys: 0x9e72e000, virt: 0x9e72e000, size: 0x1000, bootServicesData, attrs: 0x8
phys: 0x9e72f000, virt: 0x9e72f000, size: 0x1000, runtimeServicesData, attrs: 0x8000000000000008
phys: 0x9e730000, virt: 0x9e730000, size: 0x2000, bootServicesData, attrs: 0x8
phys: 0x9e732000, virt: 0x9e732000, size: 0x1000, reservedMemoryType, attrs: 0x8
phys: 0x9e733000, virt: 0x9e733000, size: 0x3000, runtimeServicesData, attrs: 0x8000000000000008
phys: 0x9e736000, virt: 0x9e736000, size: 0x1000, bootServicesData, attrs: 0x8
phys: 0x9e737000, virt: 0x9e737000, size: 0x4000, runtimeServicesData, attrs: 0x8000000000000008
phys: 0x9e73b000, virt: 0x9e73b000, size: 0x1000, bootServicesData, attrs: 0x8
phys: 0x9e73c000, virt: 0x9e73c000, size: 0x2000, reservedMemoryType, attrs: 0x8
phys: 0x9e73e000, virt: 0x9e73e000, size: 0x2000, bootServicesData, attrs: 0x8
phys: 0x9e740000, virt: 0x9e740000, size: 0x1000, reservedMemoryType, attrs: 0x8
phys: 0x9e741000, virt: 0x9e741000, size: 0x2000, bootServicesData, attrs: 0x8
phys: 0x9e743000, virt: 0x9e743000, size: 0x1822000, loaderData, attrs: 0x8
phys: 0x9ff65000, virt: 0x9ff65000, size: 0x1000, runtimeServicesCode, attrs: 0x8000000000000008
phys: 0x9ff66000, virt: 0x9ff66000, size: 0x9a000, loaderData, attrs: 0x8
physMemRange: 0x80020000, 0x1ffe0000
MapRange(0x3fe0020000, 0x80020000, 0x1ffe0000)
MapRange(0x40008000, 0x40008000, 0x10)
MapRange(0xc000000, 0xc000000, 0x210000)
MapRange(0x2000000, 0x2000000, 0x10000)
MapRange(0x10000000, 0x10000000, 0x100)
MapRange(0x9c0f7000, 0x9c0f7000, 0x25db000)
MapRange(0x9e6d2000, 0x9e6d2000, 0x55000)
MapRange(0x9e743000, 0x9e743000, 0x1822000)
MapRange(0x9ff66000, 0x9ff66000, 0x9a000)
Kernel entry point
platform1: sbi
platform2: efi
arch_debug_init_early()
image "kernel_riscv64"
text: 0x9c4dd000 - 0x9c659000, 474861568
data: 0x9c659000 - 0x9c6c2000, 474861568
image "session"
text: 0x9c10c000 - 0x9c10f000, 2618343424
data: 0x9c10f000 - 0x9c110000, 2618343424
image "write_overlay"
text: 0x9c110000 - 0x9c116000, 2618359808
data: 0x9c116000 - 0x9c117000, 2618359808
image "udf"
text: 0x9c117000 - 0x9c123000, 2618388480
data: 0x9c123000 - 0x9c124000, 2618388480
image "reiserfs"
text: 0x9c134000 - 0x9c143000, 2618507264
data: 0x9c143000 - 0x9c144000, 2618507264
image "ntfs"
text: 0x9c144000 - 0x9c194000, 2618572800
data: 0x9c194000 - 0x9c198000, 2618572800
image "log_overlay"
text: 0x9c198000 - 0x9c1a0000, 2618916864
data: 0x9c1a0000 - 0x9c1a1000, 2618916864
image "iso9660"
text: 0x9c1b1000 - 0x9c1b5000, 2619019264
data: 0x9c1b5000 - 0x9c1b6000, 2619019264
image "fat"
text: 0x9c1b6000 - 0x9c1d2000, 2619039744
data: 0x9c1d2000 - 0x9c1d4000, 2619039744
image "ext2"
text: 0x9c1e4000 - 0x9c206000, 2619228160
data: 0x9c206000 - 0x9c208000, 2619228160
image "exfat"
text: 0x9c208000 - 0x9c20f000, 2619375616
data: 0x9c20f000 - 0x9c210000, 2619375616
image "btrfs"
text: 0x9c210000 - 0x9c228000, 2619408384
data: 0x9c228000 - 0x9c229000, 2619408384
image "bindfs"
text: 0x9c229000 - 0x9c22d000, 2619510784
data: 0x9c22d000 - 0x9c22e000, 2619510784
image "attribute_overlay"
text: 0x9c23e000 - 0x9c243000, 2619596800
data: 0x9c243000 - 0x9c244000, 2619596800
image "xhci"
text: 0x9c244000 - 0x9c259000, 2619621376
data: 0x9c259000 - 0x9c25a000, 2619621376
image "virtio_scsi"
text: 0x9c25a000 - 0x9c25e000, 2619711488
data: 0x9c25e000 - 0x9c25f000, 2619711488
image "virtio_pci"
text: 0x9c25f000 - 0x9c261000, 2619731968
data: 0x9c261000 - 0x9c262000, 2619731968
image "virtio_mmio"
text: 0x9c262000 - 0x9c266000, 2619744256
data: 0x9c266000 - 0x9c267000, 2619744256
image "virtio_block"
text: 0x9c267000 - 0x9c26a000, 2619764736
data: 0x9c26a000 - 0x9c26b000, 2619764736
image "virtio"
text: 0x9c27b000 - 0x9c280000, 2619846656
data: 0x9c280000 - 0x9c281000, 2619846656
image "usb_disk"
text: 0x9c281000 - 0x9c292000, 2619871232
data: 0x9c292000 - 0x9c297000, 2619871232
image "usb"
text: 0x9c297000 - 0x9c2a5000, 2619961344
data: 0x9c2a5000 - 0x9c2a6000, 2619961344
image "uhci"
text: 0x9c2a6000 - 0x9c2b8000, 2620022784
data: 0x9c2b8000 - 0x9c2b9000, 2620022784
image "silicon_image_3112"
text: 0x9c2c9000 - 0x9c2cc000, 2620166144
data: 0x9c2cc000 - 0x9c2cd000, 2620166144
image "sdhci_pci"
text: 0x9c2cd000 - 0x9c2d2000, 2620182528
data: 0x9c2d2000 - 0x9c2d3000, 2620182528
image "scsi_periph"
text: 0x9c2d3000 - 0x9c2d7000, 2620207104
data: 0x9c2d7000 - 0x9c2d8000, 2620207104
image "scsi_disk"
text: 0x9c2d8000 - 0x9c2da000, 2620227584
data: 0x9c2da000 - 0x9c2db000, 2620227584
image "scsi_cd"
text: 0x9c2db000 - 0x9c2de000, 2620239872
data: 0x9c2de000 - 0x9c2df000, 2620239872
image "scsi"
text: 0x9c2df000 - 0x9c2e6000, 2620256256
data: 0x9c2e6000 - 0x9c2e7000, 2620256256
image "pci"
text: 0x9c2e7000 - 0x9c2f3000, 2620289024
data: 0x9c2f3000 - 0x9c2f4000, 2620289024
image "packagefs"
text: 0x9c31e000 - 0x9c375000, 2620514304
data: 0x9c375000 - 0x9c37a000, 2620514304
image "ohci"
text: 0x9c38a000 - 0x9c39c000, 2620956672
data: 0x9c39c000 - 0x9c39d000, 2620956672
image "nvme_disk"
text: 0x9c39d000 - 0x9c3a9000, 2621034496
data: 0x9c3a9000 - 0x9c3aa000, 2621034496
image "mmc_disk"
text: 0x9c3aa000 - 0x9c3ad000, 2621087744
data: 0x9c3ad000 - 0x9c3ae000, 2621087744
image "mmc"
text: 0x9c3ae000 - 0x9c3b1000, 2621104128
data: 0x9c3b1000 - 0x9c3b2000, 2621104128
image "locked_pool"
text: 0x9c3b2000 - 0x9c3b4000, 2621120512
data: 0x9c3b4000 - 0x9c3b5000, 2621120512
image "legacy_sata"
text: 0x9c3b5000 - 0x9c3b7000, 2621132800
data: 0x9c3b7000 - 0x9c3b8000, 2621132800
image "it8211"
text: 0x9c3b8000 - 0x9c3b9000, 2621145088
data: 0x9c3b9000 - 0x9c3ba000, 2621145088
image "intel"
text: 0x9c3ca000 - 0x9c3d5000, 2621218816
data: 0x9c3d5000 - 0x9c3d7000, 2621218816
image "highpoint_ide_pci"
text: 0x9c3d7000 - 0x9c3d9000, 2621272064
data: 0x9c3d9000 - 0x9c3da000, 2621272064
image "generic_ide_pci"
text: 0x9c3da000 - 0x9c3db000, 2621284352
data: 0x9c3db000 - 0x9c3dc000, 2621284352
image "fdt"
text: 0x9c3dc000 - 0x9c3e2000, 2621292544
data: 0x9c3e2000 - 0x9c3e3000, 2621292544
image "ehci"
text: 0x9c3e3000 - 0x9c3f7000, 2621321216
data: 0x9c3f7000 - 0x9c3f8000, 2621321216
image "efi_gpt"
text: 0x9c408000 - 0x9c413000, 2621472768
data: 0x9c413000 - 0x9c415000, 2621472768
image "dpc"
text: 0x9c415000 - 0x9c416000, 2621526016
data: 0x9c416000 - 0x9c417000, 2621526016
image "config_manager"
text: 0x9c417000 - 0x9c418000, 2621534208
data: 0x9c418000 - 0x9c419000, 2621534208
image "bfs"
text: 0x9c422000 - 0x9c454000, 2621579264
data: 0x9c454000 - 0x9c456000, 2621579264
image "ata_adapter"
text: 0x9c456000 - 0x9c458000, 2621792256
data: 0x9c458000 - 0x9c459000, 2621792256
image "ata"
text: 0x9c459000 - 0x9c462000, 2621804544
data: 0x9c462000 - 0x9c463000, 2621804544
image "ahci"
text: 0x9c463000 - 0x9c46e000, 2621845504
data: 0x9c46e000 - 0x9c470000, 2621845504
Welcome to kernel debugger output!
Haiku revision: , debug level: 2
INIT: init CPU
INIT: init interrupts
reserve_io_interrupt_vectors: reserved 64 vectors starting from 0
INIT: init VM
vm_translation_map_init: entry
kernel args ranges:
9c6c2000 - 9c6d2000
9c470000 - 9c4dd000
9c419000 - 9c422000
9c3f8000 - 9c408000
9c3ba000 - 9c3ca000
9c37a000 - 9c38a000
9c2f4000 - 9c31e000
9c2b9000 - 9c2c9000
9c26b000 - 9c27b000
9c22e000 - 9c23e000
9c1d4000 - 9c1e4000
9c1a1000 - 9c1b1000
9c124000 - 9c134000
9c0fc000 - 9c10c000
physical memory ranges:
80020000 - 87efb000
87f05000 - 9e727000
9e743000 - 9ff65000
9ff66000 - a0000000
allocated physical ranges:
9bed1000 - 9e6d2000
9e743000 - 9ff65000
9ff66000 - a0000000
allocated virtual ranges:
9c0f7000 - 9c6d2000
physMapBase: 0x3fe0020000
physMemBase: 0x80020000
mark_page_range_in_use(0x0, 0x80020): start page is before free list
vm_translation_map_init_post_area: entry
Nice work!! What was causing the issues jumping into the kernel from EFI? I assumed it was the SV39 page tables not being properly setup… but still not sure.
Be sure to keep those patches coming into Gerrit. I’m pausing reviewing them until tomorrow since the R1 / Beta 3 branch is so close.
– Alex
I implemented my own MMU code in both “efi” and “riscv” platforms, there are no machine mode and page table setup code in kernel anymore. There are some tricky things such as arch_enter_kernel()
function code should be identity mapped, otherwise it will crash after setting SATP register. Also boot loader maps MMIO registers of some devices such as UART, PLIC, CLINT.
Page table initialization code looks very nice:
static void
SetupPageTable()
{
sPageTable = AllocPhysPage();
PreallocKernelRange();
// Physical memory mapping
gKernelArgs.arch_args.physMap.size
= gKernelArgs.physical_memory_range[0].size;
gKernelArgs.arch_args.physMap.start = KERNEL_TOP + 1
- gKernelArgs.arch_args.physMap.size;
MapRange(gKernelArgs.arch_args.physMap.start,
gKernelArgs.physical_memory_range[0].start,
gKernelArgs.arch_args.physMap.size,
(1 << pteRead) | (1 << pteWrite));
// Boot loader
MapRangeIdentity((addr_t)gMemBase, &gStackEnd - gMemBase,
(1 << pteRead) | (1 << pteWrite) | (1 << pteExec));
// Memory regions
MemoryRegion* region;
for (region = sRegions; region != NULL; region = region->next) {
uint64 flags = 0;
if ((region->protection & B_READ_AREA) != 0)
flags |= (1 << pteRead);
if ((region->protection & B_WRITE_AREA) != 0)
flags |= (1 << pteWrite);
if ((region->protection & B_EXECUTE_AREA) != 0)
flags |= (1 << pteExec);
MapRange(region->virtAdr, region->physAdr, region->size, flags);
}
// Devices
MapAddrRange(gKernelArgs.arch_args.clint, (1 << pteRead) | (1 << pteWrite));
MapAddrRange(gKernelArgs.arch_args.htif, (1 << pteRead) | (1 << pteWrite));
MapAddrRange(gKernelArgs.arch_args.plic, (1 << pteRead) | (1 << pteWrite));
if (gKernelArgs.arch_args.uart.kind != kUartKindNone) {
MapAddrRange(gKernelArgs.arch_args.uart.regs,
(1 << pteRead) | (1 << pteWrite));
}
}
EFI version:
uint64
arch_mmu_generate_post_efi_page_tables(size_t memory_map_size,
efi_memory_descriptor *memory_map, size_t descriptor_size,
uint32_t descriptor_version)
{
sPageTable = mmu_allocate_page();
memset(VirtFromPhys(sPageTable), 0, B_PAGE_SIZE);
PreallocKernelRange();
gKernelArgs.arch_args.num_virtual_ranges_to_keep = 0;
FillPhysicalMemoryMap(memory_map_size, memory_map, descriptor_size, descriptor_version);
addr_range physMemRange;
GetPhysMemRange(physMemRange);
printf("physMemRange: 0x%" B_PRIxADDR ", 0x%" B_PRIxSIZE "\n", physMemRange.start, physMemRange.size);
// Physical memory mapping
gKernelArgs.arch_args.physMap.start = KERNEL_TOP + 1 - physMemRange.size;
gKernelArgs.arch_args.physMap.size = physMemRange.size;
MapRange(gKernelArgs.arch_args.physMap.start, physMemRange.start, physMemRange.size, (1 << pteRead) | (1 << pteWrite));
// Devices
MapAddrRange(gKernelArgs.arch_args.clint, (1 << pteRead) | (1 << pteWrite));
MapAddrRange(gKernelArgs.arch_args.htif, (1 << pteRead) | (1 << pteWrite));
MapAddrRange(gKernelArgs.arch_args.plic, (1 << pteRead) | (1 << pteWrite));
if (gKernelArgs.arch_args.uart.kind != kUartKindNone) {
MapAddrRange(gKernelArgs.arch_args.uart.regs,
(1 << pteRead) | (1 << pteWrite));
}
for (size_t i = 0; i < memory_map_size / descriptor_size; ++i) {
efi_memory_descriptor* entry = &memory_map[i];
switch (entry->Type) {
case EfiLoaderCode:
case EfiLoaderData:
MapRange(entry->VirtualStart, entry->PhysicalStart, entry->NumberOfPages * B_PAGE_SIZE, (1 << pteRead) | (1 << pteWrite) | (1 << pteExec));
break;
default:
;
}
}
return GetSatp();
}
Another GCC behavior that makes me angry: it produce wrong stack frames for leaf functions even if -fno-omit-frame-pointer
is provided: Clang, GCC. GCC put previous frame pointer at wrong offset for leaf functions.
This cause broken stack traces:
PANIC: vm_page_fault: unhandled page fault in kernel space at 0xffffffff4a70e940, ip 0x100171978
Welcome to Kernel Debugging Land...
Thread 444 "app_server" running on CPU 0
Stack:
FP: 0x100a29e30
FP: 0x100a29f40, PC: 0x1001655f9 <kernel_riscv64> arch_debug_call_with_fault_handler + 91
FP: 0x100a29f90, PC: 0x1000ddb89 <kernel_riscv64> debug_call_with_fault_handler.localalias.7 + 129
FP: 0x100a2a020, PC: 0x1000df1c9 <kernel_riscv64> _ZL20kernel_debugger_loopPKcS0_Pvi + 299
FP: 0x100a2a090, PC: 0x1000df4b5 <kernel_riscv64> _ZL24kernel_debugger_internalPKcS0_Pvi + 135
FP: 0x100a2a0d0, PC: 0x1000df7fd <kernel_riscv64> panic + 101
FP: 0x100a2a200, PC: 0x100152bcd <kernel_riscv64> vm_page_fault + 541
FP: 0x100a2a2e0, PC: 0x100166591 <kernel_riscv64> STrap + 255
FP: 0x100a2a3e0, PC: 0x10016482d <kernel_riscv64> SVec + 77
FP: 0x100a2a3f0, PC: 0x100171977 <kernel_riscv64> strcpy + 15
FP: 0x8198cb80, PC: 0x100a2a4df <app_server_444_kstack> 0x44df // PC is really FP here and FP is garbage
FP: 0xde01d898, PC: 0x0 0x0
FP: 0x8198d3f0, PC: 0x8104b47f <slab area> 0x4b47f
FP: 0x0, PC: 0x2 0x2
kdebug>
I also have GCC some workarounds for code that works fine in Mini OS and Clang.
Someday I will probably throw away GCC and fully switch to Clang. GCC is terrible in all ways including ancient autotools build system that also cause troubles when crosscompiling on Haiku.
FreeBSD already switched to Clang.