mirror of
https://github.com/iceHtwoO/novaOS.git
synced 2026-04-17 04:32:27 +00:00
Refactor and reorganize project structure
This commit is contained in:
85
src/pi3/mailbox.rs
Normal file
85
src/pi3/mailbox.rs
Normal file
@@ -0,0 +1,85 @@
|
||||
use crate::{read_address, write_address};
|
||||
use nova_error::NovaError;
|
||||
|
||||
const MBOX_BASE: u32 = 0x3F00_0000 + 0xB880;
|
||||
|
||||
// MB0
|
||||
const MBOX_READ: u32 = MBOX_BASE;
|
||||
const MBOX_STATUS: u32 = MBOX_BASE + 0x18;
|
||||
|
||||
// MB1
|
||||
const MBOX_WRITE: u32 = MBOX_BASE + 0x20;
|
||||
|
||||
// Status
|
||||
const MAIL_FULL: u32 = 0x80000000;
|
||||
const MAIL_EMPTY: u32 = 0x40000000;
|
||||
|
||||
const HEADER_LENGTH: usize = 4 + 4 + 4 + 4 + 4; // Total Size + Request + Tag + MaxBufferLength + RequestLength
|
||||
const FOOTER_LENGTH: usize = 4;
|
||||
|
||||
macro_rules! max {
|
||||
($a:expr, $b:expr) => {{
|
||||
const M: usize = if $a > $b { $a as usize } else { $b as usize };
|
||||
M
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! mailbox_command {
|
||||
($name:ident, $tag:expr, $request_len:expr,$response_len:expr) => {
|
||||
/// More information at: <https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface>
|
||||
pub fn $name(
|
||||
request_data: [u32; $request_len / 4],
|
||||
) -> Result<[u32; $response_len / 4], NovaError> {
|
||||
let mut mailbox =
|
||||
[0u32; (HEADER_LENGTH + max!($request_len, $response_len) + FOOTER_LENGTH) / 4];
|
||||
mailbox[0] = (HEADER_LENGTH + max!($request_len, $response_len) + FOOTER_LENGTH) as u32; // Total length in Bytes
|
||||
mailbox[1] = 0; // Request
|
||||
mailbox[2] = $tag; // Command Tag
|
||||
mailbox[3] = max!($request_len, $response_len) as u32; // Max value buffer size
|
||||
mailbox[4] = $request_len;
|
||||
|
||||
mailbox[5..(5 + ($request_len / 4))].copy_from_slice(&request_data);
|
||||
mailbox[(5 + ($request_len / 4))..].fill(0);
|
||||
|
||||
let addr = core::ptr::addr_of!(mailbox[0]) as u32;
|
||||
|
||||
write_mailbox(8, addr);
|
||||
|
||||
let _ = read_mailbox(8);
|
||||
|
||||
if mailbox[1] == 0 {
|
||||
return Err(NovaError::Mailbox);
|
||||
}
|
||||
|
||||
let mut out = [0u32; $response_len / 4];
|
||||
out.copy_from_slice(&mailbox[5..(5 + $response_len / 4)]);
|
||||
Ok(out)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
mailbox_command!(read_soc_temp, 0x0003_0006, 4, 8);
|
||||
|
||||
// Framebuffer
|
||||
mailbox_command!(get_display_resolution, 0x0004_0003, 0, 8);
|
||||
|
||||
pub fn read_mailbox(channel: u32) -> u32 {
|
||||
// Wait until mailbox is not empty
|
||||
loop {
|
||||
while unsafe { read_address(MBOX_STATUS) } & MAIL_EMPTY != 0 {}
|
||||
let mut data = unsafe { read_address(MBOX_READ) };
|
||||
let read_channel = data & 0xF;
|
||||
|
||||
data >>= 4;
|
||||
|
||||
if channel == read_channel {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_mailbox(channel: u32, data: u32) {
|
||||
while unsafe { read_address(MBOX_STATUS) } & MAIL_FULL != 0 {}
|
||||
unsafe { write_address(MBOX_WRITE, (data & !0xF) | (channel & 0xF)) };
|
||||
}
|
||||
2
src/pi3/mod.rs
Normal file
2
src/pi3/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod mailbox;
|
||||
pub mod power_management;
|
||||
27
src/pi3/power_management.rs
Normal file
27
src/pi3/power_management.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
use core::ptr::{read_volatile, write_volatile};
|
||||
|
||||
use crate::PERIPHERAL_BASE;
|
||||
|
||||
/// Power Management Base
|
||||
static PM_BASE: u32 = PERIPHERAL_BASE + 0x10_0000;
|
||||
static PM_RSTC: u32 = PM_BASE + 0x1c;
|
||||
static PM_WDOG: u32 = PM_BASE + 0x24;
|
||||
|
||||
static PM_PASSWORD: u32 = 0x5a000000;
|
||||
static PM_WDOG_TIMER_MASK: u32 = 0x000fffff;
|
||||
static PM_RSTC_WRCFG_CLR: u32 = 0xffffffcf;
|
||||
static PM_RSTC_WRCFG_FULL_RESET: u32 = 0x00000020;
|
||||
|
||||
pub fn reboot_system() {
|
||||
unsafe {
|
||||
let pm_rstc_val = read_volatile(PM_RSTC as *mut u32);
|
||||
// (31:16) bits -> password
|
||||
// (11:0) bits -> value
|
||||
write_volatile(PM_WDOG as *mut u32, PM_PASSWORD | (1 & PM_WDOG_TIMER_MASK));
|
||||
write_volatile(
|
||||
PM_RSTC as *mut u32,
|
||||
PM_PASSWORD | (pm_rstc_val & PM_RSTC_WRCFG_CLR) | PM_RSTC_WRCFG_FULL_RESET,
|
||||
);
|
||||
}
|
||||
loop {}
|
||||
}
|
||||
Reference in New Issue
Block a user