Do not hardcode aarch64 uart

This commit is contained in:
Jeremy Soller
2021-05-06 13:16:50 -06:00
parent c4617c0bce
commit 2e38fab913
6 changed files with 31 additions and 49 deletions

View File

@@ -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

View File

@@ -9,28 +9,19 @@ use crate::paging::{ActivePageTable, Page, PageFlags, PhysicalAddress, TableKind
pub static COM1: Mutex<Option<SerialPort>> = 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);
}

View File

@@ -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) }
}

View File

@@ -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::<Vec<&str>>()[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();

View File

@@ -149,16 +149,16 @@ unsafe fn inner<A: Arch>(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::<A>(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

View File

@@ -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;