diff --git a/src/arch/aarch64/consts.rs b/src/arch/aarch64/consts.rs index 12a49bb..d3834ef 100644 --- a/src/arch/aarch64/consts.rs +++ b/src/arch/aarch64/consts.rs @@ -37,13 +37,9 @@ /// Offset of temporary mapping for misc kernel bring-up actions pub const KERNEL_TMP_MISC_OFFSET: usize = KERNEL_ENV_OFFSET - PML4_SIZE; - /// Offset of FDT DTB image - pub const KERNEL_DTB_OFFSET: usize = KERNEL_TMP_MISC_OFFSET - PML4_SIZE; - pub const KERNEL_DTB_MAX_SIZE: usize = 2 * 1024 * 1024; // 2 MB - /// Offset to kernel percpu variables //TODO: Use 64-bit fs offset to enable this pub const KERNEL_PERCPU_OFFSET: usize = KERNEL_HEAP_OFFSET - PML4_SIZE; - pub const KERNEL_PERCPU_OFFSET: usize = KERNEL_DTB_OFFSET - PML4_SIZE; + pub const KERNEL_PERCPU_OFFSET: usize = KERNEL_TMP_MISC_OFFSET - PML4_SIZE; /// Size of kernel percpu variables pub const KERNEL_PERCPU_SIZE: usize = 64 * 1024; // 64 KB diff --git a/src/arch/aarch64/device/serial.rs b/src/arch/aarch64/device/serial.rs index d4abe9d..b78801a 100644 --- a/src/arch/aarch64/device/serial.rs +++ b/src/arch/aarch64/device/serial.rs @@ -9,28 +9,19 @@ use crate::paging::{ActivePageTable, Page, PageFlags, PhysicalAddress, TableKind pub static COM1: Mutex> = Mutex::new(None); -pub unsafe fn init() { - if COM1.lock().is_none() { - let (base, size) = device_tree::diag_uart_range(crate::KERNEL_DTB_OFFSET, crate::KERNEL_DTB_MAX_SIZE).unwrap(); - - let mut active_ktable = unsafe { ActivePageTable::new(TableKind::Kernel) }; - let mut flush_all = PageFlushAll::new(); - - let start_frame = Frame::containing_address(PhysicalAddress::new(base)); - let end_frame = Frame::containing_address(PhysicalAddress::new(base + size - 1)); - for frame in Frame::range_inclusive(start_frame, end_frame) { - let page = Page::containing_address(VirtualAddress::new(frame.start_address().data() + crate::KERNEL_DEVMAP_OFFSET)); - let result = active_ktable.map_to(page, frame, PageFlags::new().write(true)); - flush_all.consume(result); - }; - flush_all.flush(); - - let start_frame = Frame::containing_address(PhysicalAddress::new(base)); - let vaddr = start_frame.start_address().data() + crate::KERNEL_DEVMAP_OFFSET; - - *COM1.lock() = Some(SerialPort::new(vaddr)); +pub unsafe fn init_early(dtb_base: usize, dtb_size: usize) { + if let Some((phys, size)) = device_tree::diag_uart_range(dtb_base, dtb_size) { + let virt = crate::KERNEL_DEVMAP_OFFSET + phys; + { + let mut serial_port = SerialPort::new(virt); + serial_port.init(false); + *COM1.lock() = Some(serial_port); + } + println!("UART at {:X}", virt); } +} +pub unsafe fn init() { if let Some(ref mut serial_port) = *COM1.lock() { serial_port.init(true); } diff --git a/src/arch/aarch64/device/uart_pl011.rs b/src/arch/aarch64/device/uart_pl011.rs index ef9f778..cc5db94 100644 --- a/src/arch/aarch64/device/uart_pl011.rs +++ b/src/arch/aarch64/device/uart_pl011.rs @@ -95,6 +95,10 @@ impl SerialPort { } } + pub fn base(&self) -> usize { + self.base + } + pub fn read_reg(&self, register: u8) -> u16 { unsafe { ptr::read_volatile((self.base + register as usize) as *mut u16) } } diff --git a/src/arch/aarch64/init/device_tree/mod.rs b/src/arch/aarch64/init/device_tree/mod.rs index cff4047..b956a46 100644 --- a/src/arch/aarch64/init/device_tree/mod.rs +++ b/src/arch/aarch64/init/device_tree/mod.rs @@ -55,7 +55,8 @@ pub fn diag_uart_range(dtb_base: usize, dtb_size: usize) -> Option<(usize, usize let stdout_path = chosen_node.properties().find(|p| p.name.contains("stdout-path")).unwrap(); let uart_node_name = core::str::from_utf8(stdout_path.data).unwrap() .split('/') - .collect::>()[1].trim_end(); + .nth(1)? + .trim_end(); let len = uart_node_name.len(); let uart_node_name = &uart_node_name[0..len-1]; let uart_node = dt.nodes().find(|n| n.name.contains(uart_node_name)).unwrap(); diff --git a/src/arch/aarch64/rmm.rs b/src/arch/aarch64/rmm.rs index 8cff242..6659082 100644 --- a/src/arch/aarch64/rmm.rs +++ b/src/arch/aarch64/rmm.rs @@ -149,16 +149,16 @@ unsafe fn inner(areas: &'static [MemoryArea], kernel_base: usize, kerne } //TODO: this is another hack to map our UART - { - let phys = PhysicalAddress::new(0x9000000); - let virt = A::phys_to_virt(phys); - let flags = page_flags::(virt); - let flush = mapper.map_phys( - virt, - phys, - flags - ).expect("failed to map frame"); - flush.ignore(); // Not the active table + match crate::device::serial::COM1.lock().as_ref().map(|x| x.base()) { + Some(serial_base) => { + let flush = mapper.map_phys( + VirtualAddress::new(serial_base), + PhysicalAddress::new(serial_base - crate::KERNEL_DEVMAP_OFFSET), + PageFlags::new().write(true) + ).expect("failed to map frame"); + flush.ignore(); // Not the active table + }, + None => (), } //TODO: remove backwards compatible recursive mapping diff --git a/src/arch/aarch64/start.rs b/src/arch/aarch64/start.rs index b30c649..e32c3a3 100644 --- a/src/arch/aarch64/start.rs +++ b/src/arch/aarch64/start.rs @@ -60,19 +60,6 @@ pub unsafe extern fn kstart(args_ptr: *const KernelArgs) -> ! { let dtb_base = args.dtb_base as usize; let dtb_size = args.dtb_size as usize; - //TODO: remove this hack for early console, use device tree - { - let mut serial = device::uart_pl011::SerialPort::new(crate::KERNEL_DEVMAP_OFFSET + 0x9000000); - serial.init(false); - serial.send(b'T'); - serial.send(b'E'); - serial.send(b'S'); - serial.send(b'T'); - serial.send(b'\r'); - serial.send(b'\n'); - *device::serial::COM1.lock() = Some(serial); - } - // BSS should already be zero { assert_eq!(BSS_TEST_ZERO, 0); @@ -82,6 +69,9 @@ pub unsafe extern fn kstart(args_ptr: *const KernelArgs) -> ! { KERNEL_BASE.store(kernel_base, Ordering::SeqCst); KERNEL_SIZE.store(kernel_size, Ordering::SeqCst); + // Try to find serial port prior to logging + device::serial::init_early(crate::KERNEL_DEVMAP_OFFSET + dtb_base, dtb_size); + // Initialize logger log::init_logger(|r| { use core::fmt::Write;