bringup raspi3b+, add device memory, disable uart init
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
@@ -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")]
|
||||
|
||||
@@ -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);
|
||||
*/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user