You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
peari9jp6/kernel/src/arch/aarch64/board/raspi3/mod.rs

88 lines
2.3 KiB

//! Raspberry PI 3 Model B/B+
use bcm2837::atags::Atags;
use once::*;
use alloc::string::String;
#[path = "../../../../drivers/gpu/fb.rs"]
pub mod fb;
pub mod irq;
pub mod mailbox;
pub mod serial;
pub mod timer;
use fb::FramebufferInfo;
pub const IO_REMAP_BASE: usize = bcm2837::consts::IO_BASE;
pub const IO_REMAP_END: usize = bcm2837::consts::KERNEL_OFFSET + 0x4000_1000;
/// Initialize serial port before other initializations.
pub fn init_serial_early() {
assert_has_not_been_called!("board::init must be called only once");
serial::init();
println!("Hello Raspberry Pi!");
}
/// Initialize raspi3 drivers
pub fn init_driver() {
#[cfg(not(feature = "nographic"))]
fb::init();
timer::init();
}
/// Returns the (start address, end address) of the physical memory on this
/// system if it can be determined. If it cannot, `None` is returned.
///
/// This function is expected to return `Some` under all normal cirumstances.
pub fn probe_memory() -> Option<(usize, usize)> {
let mut atags: Atags = Atags::get();
while let Some(atag) = atags.next() {
if let Some(mem) = atag.mem() {
return Some((mem.start as usize, (mem.start + mem.size) as usize));
}
}
None
}
pub fn probe_fb_info(width: u32, height: u32, depth: u32) -> Result<(FramebufferInfo, usize), String> {
let (width, height) = if width == 0 || height == 0 {
mailbox::framebuffer_get_physical_size()?
} else {
(width, height)
};
let depth = if depth == 0 {
mailbox::framebuffer_get_depth()?
} else {
depth
};
let info = mailbox::framebuffer_alloc(width, height, depth)?;
if info.bus_addr == 0 || info.screen_size == 0 {
Err(format!("mailbox call returned an invalid address/size"))?;
}
if info.pitch == 0 || info.pitch != info.xres * info.depth / 8 {
Err(format!(
"mailbox call returned an invalid pitch value {}",
info.pitch
))?;
}
use crate::arch::memory;
let paddr = info.bus_addr & !0xC0000000;
let vaddr = memory::ioremap(paddr as usize, info.screen_size as usize, "fb");
if vaddr == 0 {
Err(format!(
"cannot remap memory range [{:#x?}..{:#x?}]",
paddr,
paddr + info.screen_size
))?;
}
Ok((info, vaddr))
}