Repository: oreboot/oreboot (language: rust)

Issue:
qemu-q35 debug port print breaks boot
When running `make run` for qemu-q35 I can not get past the first print onto the debug port [here](https://github.com/oreboot/oreboot/blob/main/src/mainboard/emulation/qemu-q35/src/main.rs#L30-L32). 

When this line is commented out I can at least get up to loading the payload (L47), at which a panic will occur and the following message will be printed forever:
```
Welcome to oreboot                                                                                       
boot flag is ffff, not aa55, at ffff,                                                                                                                                                                              
                                                                                                                                                                                                                   
PANIC: Welcome to oreboot                                                                                                                                                                                          
boot flag is ffff, not aa55, at ffff,                                                                                                                                                                              
                                                                                                         
PANIC: Welcome to oreboot                                                                                                                                                                                          
boot flag is ffff, not aa55, at ffff,
```

Hopefully I will be able to resolve it myself, but maybe someone knows whats wrong here :)


Discussion / hints:
This is the content of SetupHeader, before it throws the error ([this](https://github.com/oreboot/binaries/blob/master/rminnich/romecrb/orebootkernel) payload):
```
SetupHeader: SetupHeader {
    setup_sects: 0x1a,
    root_flags: 0xdb00,
    syssize: 0x257,
    ram_size: 0xff00,
    vid_mode: 0xff,
    root_dev: 0x5500,
    boot_flag: 0xebaa,
    jump: 0x486a,
    header: 0x20f53,
    version: 0x0,
    realmode_swtch: 0x324010,
    start_sys: 0x1,
    kernel_version: 0x80,
    type_of_loader: 0x0,
    loadflags: 0x10,
    setup_move_size: 0x0,
    code32_start: 0x0,
    ramdisk_image: 0x0,
    ramdisk_size: 0x10000000,
    bootsect_kludge: 0x4b,
    heap_end_ptr: 0x0,
    ext_loader_ver: 0x0,
    ext_loader_type: 0xff,
    cmd_line_ptr: 0x7fffff,
    initrd_addr_max: 0x2000,
    kernel_alignment: 0xff002115,
    relocatable_kernel: 0x7,
    min_alignment: 0x0,
    xloadflags: 0x0,
    cmdline_size: 0x0,
    hardware_subarch: 0x0,
    hardware_subarch_data: 0x252ca0000002,
    payload_offset: 0x0,
    payload_length: 0x0,
    setup_data: 0x10000,
    pref_address: 0x580000000000cfa0,
    init_size: 0x8c002575,
    handover_offset: 0xfcc08ed8,
    kernel_info_offset: 0xc239d28c,
}
```
Looking at `root_dev` and `boot_flag` I first thought the offset might be off by one, but the docs agree with the set offset: https://www.kernel.org/doc/html/latest/x86/boot.html#the-real-mode-kernel-header.
Also the `header` does not match the expected value :/
Commenting out the entire declaration of debug, its init and the pwrite, I do get that payload to run, with the Linux kernel eventually panicking.

With a kernel from Arch, I get an endless loop of

```
Welcome to oreboot
Kernel offset is 3e00
Copy ff003e00 to 1000000 for 300000
Running payload
on to 0x1000200 Welcome to oreboot
```
That looks very similar to what I am seeing.
Looked at it again today with @jhand2 and after commenting out [this](https://github.com/oreboot/oreboot/blob/main/src/mainboard/emulation/qemu-q35/src/main.rs#L41-L43) line a kernel boots.

The problem seems to be related with the timer code [here]( https://github.com/oreboot/oreboot/blob/main/src/drivers/uart/src/debug_port.rs#L38-L42). Removing it makes everything work fine.
Interesting! That could also be related to the issue we have with the A300 port.

Fix patch:
diff --git a/src/drivers/timer/src/hpet.rs b/src/drivers/timer/src/hpet.rs
index fd3627ee87..0afd1ca980 100644
--- a/src/drivers/timer/src/hpet.rs
+++ b/src/drivers/timer/src/hpet.rs
@@ -13,6 +13,7 @@
 
 use core::ops;
 
+use tock_registers::interfaces::ReadWriteable;
 use tock_registers::interfaces::Readable;
 use tock_registers::register_bitfields;
 use tock_registers::registers::{ReadOnly, ReadWrite};
@@ -82,6 +83,16 @@ impl HPET {
         self.base as *const _
     }
 
+    pub fn enable(&self) -> Result<(), &str> {
+        // set enable bit for HPET timer as per 2.3.5
+        // https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/software-developers-hpet-spec-1-0a.pdf
+        self.config.modify(CONFIG::TMREN::SET);
+        match self.config.is_set(CONFIG::TMREN) {
+            true => Ok(()),
+            false => Err("HPET.enable() failed to set timer_enable."),
+        }
+    }
+
     // Sleeps at least the given amount of time (in fs).
     // Note: That means that DELAY cannot be much longer than 4 us.
     pub fn sleep(&self, delay: u32) {
diff --git a/src/drivers/uart/src/debug_port.rs b/src/drivers/uart/src/debug_port.rs
index 87ddf14eed..003f5cda61 100644
--- a/src/drivers/uart/src/debug_port.rs
+++ b/src/drivers/uart/src/debug_port.rs
@@ -20,9 +20,10 @@ impl<D: Driver> DebugPort<D> {
 }
 
 impl<D: Driver> Driver for DebugPort<D> {
-    // Nothing to set up here
     fn init(&mut self) -> Result<()> {
-        Ok(())
+        self.timer
+            .enable()
+            .map_err(|_| "DebugPort unusable: enable bit not set for HPET timer.")
     }
 
     // DebugPort can only be used to write, nothing here
diff --git a/src/mainboard/emulation/qemu-q35/src/main.rs b/src/mainboard/emulation/qemu-q35/src/main.rs
index c4df99138b..a4e894fb01 100644
--- a/src/mainboard/emulation/qemu-q35/src/main.rs
+++ b/src/mainboard/emulation/qemu-q35/src/main.rs
@@ -31,7 +31,7 @@ global_asm!(
 );
 
 #[no_mangle]
-pub extern "C" fn _start(fdt_address: usize) -> ! {
+pub extern "C" fn _start(_fdt_address: usize) -> ! {
     let uart0 = &mut I8250::new(0x3f8, 0, IOPort {});
     // Note: on real hardware, use port 0x80 instead for "POST" output
     let debug = &mut DebugPort::new(0xe9, IOPort {});


Test patch: