My Haiku RISC-V port progress

It is platform name, not architecture name, architecture name is “riscv64”.

Ok.

“Superfluous text to meet the minimum requirement of 12 characters.”

1 Like

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.

2 Likes

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

screenshot80

14 Likes

USB XHCI controller (USB 3) is working. Definitely useful on real hardware.

screenshot81

30 Likes

really inspiring to see all progress :slight_smile:

1 Like

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.

screenshot82

26 Likes

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.

screenshot83

10 Likes

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.

screenshot84

23 Likes

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.

screenshot85

24 Likes

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

screenshot86

25 Likes

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

1 Like

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();
}
6 Likes

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.

6 Likes