bringup raspi3b+, add device memory, disable uart init

This commit is contained in:
Ivan Tan
2023-12-02 18:52:54 +08:00
committed by Jeremy Soller
parent bfbf435546
commit 1c1c541f0e
7 changed files with 108 additions and 14 deletions
+2 -2
View File
@@ -85,9 +85,9 @@ impl InterruptController for GenericInterruptController {
//TODO: do kernel memory map using node.ranges
// Map in the Distributor interface
io_mmap(dist_addr, dist_size);
//io_mmap(dist_addr, dist_size);
// Map in CPU0's interface
io_mmap(cpu_addr, cpu_size);
//io_mmap(cpu_addr, cpu_size);
self.gic_cpu_if.init(crate::PHYS_OFFSET + cpu_addr);
self.gic_dist_if.init(crate::PHYS_OFFSET + dist_addr);
@@ -132,7 +132,7 @@ impl InterruptController for Bcm2835ArmInterruptController {
Err(_) => return Err(Error::new(EINVAL)),
};
unsafe {
io_mmap(base, size);
//io_mmap(base, size);
self.address = base + crate::PHYS_OFFSET;
@@ -116,7 +116,7 @@ impl InterruptController for Bcm2836ArmInterruptController {
Err(_) => return Err(Error::new(EINVAL)),
};
unsafe {
io_mmap(base, size);
//io_mmap(base, size);
self.address = base + crate::PHYS_OFFSET;
let mut cpuid: usize = 0;
+2 -2
View File
@@ -35,7 +35,7 @@ pub unsafe fn init_early(dtb_base: usize, dtb_size: usize) {
let virt = crate::PHYS_OFFSET + phys;
{
let mut serial_port = SerialPort::new(virt);
serial_port.init(false);
//serial_port.init(false);
*COM1.lock() = Some(serial_port);
}
println!("UART at {:X}", virt);
@@ -46,7 +46,7 @@ pub unsafe fn init() {
println!("test 1");
if let Some(ref mut serial_port) = *COM1.lock() {
serial_port.receive();
serial_port.init(true);
//serial_port.init(true);
}
println!("test 2");
let data = DTB_BINARY.get().unwrap();
+64 -3
View File
@@ -79,6 +79,65 @@ fn memory_ranges(dt: &fdt::DeviceTree, address_cells: usize, size_cells: usize,
index
}
fn dev_memory_ranges(dt: &fdt::DeviceTree, address_cells: usize, size_cells: usize, ranges: &mut [(usize, usize); 10]) -> usize {
//work around for qemu-arm64
// dev mem: 128MB - 1GB, see https://github.com/qemu/qemu/blob/master/hw/arm/virt.c for details
let root_node = dt.nodes().nth(0).unwrap();
let model = root_node.properties().find(|p| p.name.contains("model")).unwrap();
let model_str = core::str::from_utf8(model.data).unwrap();
if model_str.contains("linux,dummy-virt") {
ranges[0] = (0x08000000, 0x08000000);
ranges[1] = (0x10000000, 0x30000000);
return 2;
}
let (memory_node, _memory_cells) = dt.find_node("/soc").unwrap();
let reg = memory_node.properties().find(|p| p.name.contains("ranges")).unwrap();
let chunk_sz = (address_cells * 2 + size_cells) * 4;
let chunk_count = (reg.data.len() / chunk_sz);
let mut index = 0;
for chunk in reg.data.chunks(chunk_sz as usize) {
if index == chunk_count {
return index;
}
let child_bus_addr = {
if address_cells == 1 {
BE::read_u32(&chunk[0..4]) as u64
} else if address_cells == 2 {
BE::read_u64(&chunk[0..8])
} else {
return 0;
}
};
let parent_bus_addr = {
if address_cells == 1 {
BE::read_u32(&chunk[4..8]) as u64
} else if address_cells == 2 {
BE::read_u64(&chunk[8..16])
} else {
return 0;
}
};
let addr_size = {
if address_cells == 1 {
BE::read_u32(&chunk[8..12]) as u64
} else if address_cells == 2 {
BE::read_u64(&chunk[16..24])
} else {
return 0;
}
};
println!("dev mem 0x{:08x} 0x{:08x} 0x{:08x}", child_bus_addr, parent_bus_addr, addr_size);
ranges[index] = (parent_bus_addr as usize, addr_size as usize);
index += 1;
}
index
}
pub fn diag_uart_range(dtb_base: usize, dtb_size: usize) -> Option<(usize, usize)> {
let data = unsafe { slice::from_raw_parts(dtb_base as *const u8, dtb_size) };
let dt = fdt::DeviceTree::new(data).unwrap();
@@ -156,15 +215,17 @@ pub fn fill_memory_map(dtb_base: usize, dtb_size: usize) {
let (address_cells, size_cells) = root_cell_sz(&dt).unwrap();
let mut ranges: [(usize, usize); 10] = [(0,0); 10];
let nranges = memory_ranges(&dt, address_cells as usize, size_cells as usize, &mut ranges);
//in uefi boot mode, ignore memory node, just read the device memory range
//let nranges = memory_ranges(&dt, address_cells as usize, size_cells as usize, &mut ranges);
let nranges = dev_memory_ranges(&dt, address_cells as usize, size_cells as usize, &mut ranges);
for index in (0..nranges) {
for index in 0..nranges {
let (base, size) = ranges[index];
unsafe {
MEMORY_MAP[index] = MemoryArea {
base_addr: base as u64,
length: size as u64,
_type: 1,
_type: 2,
acpi: 0,
};
}
+26 -1
View File
@@ -22,7 +22,7 @@ use rmm::{
};
use spin::Mutex;
use crate::LogicalCpuId;
use crate::{LogicalCpuId, init::device_tree::MEMORY_MAP};
use super::CurrentRmmArch as RmmA;
@@ -160,6 +160,7 @@ unsafe fn inner<A: Arch>(
identity_map(initfs_base, initfs_size_aligned);
//TODO: this is another hack to map our UART
/*
match crate::device::serial::COM1.lock().as_ref().map(|x| x.base()) {
Some(serial_base) => {
let flush = mapper.map_phys(
@@ -171,6 +172,30 @@ unsafe fn inner<A: Arch>(
},
None => (),
}
*/
//map dev mem
for mem in MEMORY_MAP {
if mem._type == 2 {
let size_aligned = ((mem.length as usize + (A::PAGE_SIZE - 1))/A::PAGE_SIZE) * A::PAGE_SIZE;
let base = mem.base_addr as usize;
for i in 0..size_aligned / A::PAGE_SIZE {
let phys = PhysicalAddress::new(base + i * A::PAGE_SIZE);
let virt = A::phys_to_virt(phys);
// use the same mair_el1 value with bootloader,
// mair_el1 == 0x00000000000044FF
// set mem_attr == device memory
let flags = page_flags::<A>(virt)
.custom_flag(2 << 2, true);
let flush = mapper.map_phys(
virt,
phys,
flags
).expect("failed to map frame");
flush.ignore(); // Not the active table
}
}
}
// Ensure graphical debug region remains paged
#[cfg(feature = "graphical_debug")]
+12 -4
View File
@@ -56,6 +56,7 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! {
let bootstrap = {
let args = &*args_ptr;
/*
// BSS should already be zero
{
assert_eq!(BSS_TEST_ZERO, 0);
@@ -65,17 +66,21 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! {
KERNEL_BASE.store(args.kernel_base, Ordering::SeqCst);
KERNEL_SIZE.store(args.kernel_size, Ordering::SeqCst);
*/
if args.dtb_base != 0 {
// Try to find serial port prior to logging
device::serial::init_early(crate::PHYS_OFFSET + args.dtb_base, args.dtb_size);
}
KERNEL_BASE.store(args.kernel_base, Ordering::SeqCst);
KERNEL_SIZE.store(args.kernel_size, Ordering::SeqCst);
// Convert env to slice
let env = slice::from_raw_parts((args.env_base + crate::PHYS_OFFSET) as *const u8, args.env_size);
let env = slice::from_raw_parts((args.env_base) as *const u8, args.env_size);
// Set up graphical debug
#[cfg(feature = "graphical_debug")]
graphical_debug::init(env);
//graphical_debug::init(env);
// Initialize logger
log::init_logger(|r| {
@@ -107,9 +112,12 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! {
tmp = out(reg) _,
);
/* NOT USED WITH UEFI
device_tree::fill_memory_map(crate::PHYS_OFFSET + dtb_base, dtb_size);
if args.dtb_base != 0 {
//Try to read device memory map
device_tree::fill_memory_map(crate::PHYS_OFFSET + args.dtb_base, args.dtb_size);
}
/* NOT USED WITH UEFI
let env_size = device_tree::fill_env_data(crate::PHYS_OFFSET + dtb_base, dtb_size, env_base);
*/