Do not hardcode aarch64 uart
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user