mirror of
https://github.com/iceHtwoO/novaOS.git
synced 2026-04-16 20:22:26 +00:00
Trying to fix exception in el1
This commit is contained in:
41
.vscode/launch.json
vendored
41
.vscode/launch.json
vendored
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"compounds": [
|
||||
{
|
||||
"name": "Run QEMU + Attach LLDB",
|
||||
"configurations": ["Attach LLDB"],
|
||||
"preLaunchTask": "Run QEMU"
|
||||
}
|
||||
],
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Attach to QEMU (AArch64)",
|
||||
@@ -12,19 +19,29 @@
|
||||
"stopAtEntry": true,
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Show assembly on stop",
|
||||
"text": "layout asm",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Show assembly on stop",
|
||||
"text": "set disassemble-next-line on",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"preLaunchTask": "Run QEMU"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Attach LLDB",
|
||||
"type": "lldb",
|
||||
"request": "attach",
|
||||
"debugServer": 1234,
|
||||
"program": "${workspaceFolder}/target/aarch64-unknown-none/debug/nova",
|
||||
"stopOnEntry": true,
|
||||
"processCreateCommands": ["gdb-remote localhost:1234"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"lldb.displayFormat": "auto",
|
||||
"lldb.showDisassembly": "always",
|
||||
"lldb.dereferencePointers": true,
|
||||
"lldb.consoleMode": "commands"
|
||||
}
|
||||
2
.vscode/tasks.json
vendored
2
.vscode/tasks.json
vendored
@@ -14,7 +14,7 @@
|
||||
{
|
||||
"label": "Run QEMU",
|
||||
"type": "shell",
|
||||
"command": "qemu-system-aarch64 -M raspi3b -cpu cortex-a53 -serial stdio -sd sd.img -display none -kernel ${workspaceFolder}/target/aarch64-unknown-none/debug/kernel8.img -S -s",
|
||||
"command": "qemu-system-aarch64 -M raspi3b -cpu cortex-a53 -serial stdio -sd sd.img -display none -kernel ${workspaceFolder}/target/aarch64-unknown-none/debug/kernel8.img -S -s -m 1024",
|
||||
"isBackground": true,
|
||||
"dependsOn": ["Build"]
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ edition = "2021"
|
||||
|
||||
[profile.dev]
|
||||
panic = "abort"
|
||||
debug = true
|
||||
opt-level = 0
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
|
||||
BIN
firmware_files/fixup.dat
Executable file
BIN
firmware_files/fixup.dat
Executable file
Binary file not shown.
@@ -3,7 +3,10 @@ use core::{
|
||||
sync::atomic::{compiler_fence, Ordering},
|
||||
};
|
||||
|
||||
use crate::{mmio_read, mmio_write, peripherals::uart::print};
|
||||
use crate::{
|
||||
mmio_read, mmio_write,
|
||||
peripherals::{gpio::blink_gpio, uart::print},
|
||||
};
|
||||
|
||||
const INTERRUPT_BASE: u32 = 0x3F00_B000;
|
||||
const IRQ_PENDING_BASE: u32 = INTERRUPT_BASE + 0x204;
|
||||
@@ -35,7 +38,18 @@ unsafe extern "C" fn irq_handler() {
|
||||
handle_gpio_interrupt();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn synchronous_interrupt() {
|
||||
loop {
|
||||
let el: u64;
|
||||
asm!("mrs x5, FAR_EL1");
|
||||
blink_gpio(29, 100);
|
||||
print("Sync Exception \r\n");
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_gpio_interrupt() {
|
||||
print("Interrupt\r\n");
|
||||
for i in 0..=53u32 {
|
||||
let val = read_gpio_event_detect_status(i);
|
||||
|
||||
|
||||
@@ -1,26 +1,33 @@
|
||||
use crate::{mmio_read, mmio_write};
|
||||
use core::ptr::read_volatile;
|
||||
|
||||
const MBOX_BASE: u32 = 0x3F00_B880;
|
||||
use crate::{
|
||||
mmio_read, mmio_write,
|
||||
peripherals::uart::{print, print_u32},
|
||||
};
|
||||
|
||||
const MBOX_BASE: u32 = 0x3F00_0000 + 0xB880;
|
||||
|
||||
// MB0
|
||||
const MBOX_READ: u32 = MBOX_BASE + 0x00;
|
||||
const MBOX_READ_STATUS: u32 = MBOX_BASE + 0x18;
|
||||
const MBOX_STATUS: u32 = MBOX_BASE + 0x18;
|
||||
|
||||
// MB1
|
||||
const MBOX_WRITE: u32 = MBOX_BASE + 0x20;
|
||||
const MBOX_WRITE_STATUS: u32 = MBOX_BASE + 0x38;
|
||||
|
||||
// Status
|
||||
const MAIL_FULL: u32 = 0x80000000;
|
||||
const MAIL_EMPTY: u32 = 0x40000000;
|
||||
|
||||
#[repr(align(16))]
|
||||
#[repr(C, align(16))]
|
||||
struct MailboxBuffer([u32; 36]);
|
||||
|
||||
#[no_mangle]
|
||||
static mut MBOX: MailboxBuffer = MailboxBuffer([0; 36]);
|
||||
|
||||
pub fn read_mailbox(channel: u32) -> u32 {
|
||||
// Wait until mailbox is not empty
|
||||
loop {
|
||||
while (mmio_read(MBOX_READ_STATUS) & MAIL_EMPTY != 0) {}
|
||||
while mmio_read(MBOX_STATUS) & MAIL_EMPTY != 0 {}
|
||||
let mut data = mmio_read(MBOX_READ);
|
||||
let read_channel = data & 0xF;
|
||||
|
||||
@@ -33,25 +40,35 @@ pub fn read_mailbox(channel: u32) -> u32 {
|
||||
}
|
||||
|
||||
pub fn write_mailbox(channel: u32, data: u32) {
|
||||
while (mmio_read(MBOX_WRITE_STATUS) & MAIL_FULL != 0) {}
|
||||
mmio_write(MBOX_WRITE, data << 4 | (channel & 0xF));
|
||||
while mmio_read(MBOX_STATUS) & MAIL_FULL != 0 {}
|
||||
mmio_write(MBOX_WRITE, (data & !0xF) | (channel & 0xF));
|
||||
}
|
||||
|
||||
pub fn read_soc_temp() -> u32 {
|
||||
let mut mbox = MailboxBuffer([0; 36]);
|
||||
unsafe {
|
||||
// MBOX.0[0] = 7 * 4; // Total size in bytes
|
||||
// MBOX.0[1] = 0; // Request
|
||||
// MBOX.0[2] = 0x00010002; // Tag
|
||||
// MBOX.0[3] = 4; // Maximum buffer lenb
|
||||
// MBOX.0[4] = 0; // Request length
|
||||
// MBOX.0[5] = 0; // Value Buffer
|
||||
// MBOX.0[6] = 0; // End
|
||||
// core::arch::asm!("dsb sy"); // Ensure write reaches RAM
|
||||
// core::arch::asm!("dmb sy"); // Memory barrier
|
||||
|
||||
mbox.0[0] = 8 * 4; // Total size in bytes
|
||||
mbox.0[1] = 0; // Request
|
||||
mbox.0[2] = 0x00030006; // Tag: Get temperature
|
||||
mbox.0[3] = 8; // Value buffer size (bytes)
|
||||
mbox.0[4] = 4; // Request size (bytes)
|
||||
mbox.0[5] = 0; // Temp ID: 0 = SoC
|
||||
mbox.0[6] = 0; // Response will be written here
|
||||
mbox.0[7] = 0; // End tag
|
||||
print("Reading address\r\n");
|
||||
//let addr = core::ptr::addr_of!(MBOX.0[0]);
|
||||
|
||||
let addr = &mbox.0 as *const u32 as u32;
|
||||
write_mailbox(8, addr);
|
||||
let _ = read_mailbox(8);
|
||||
let raw_temp = mbox.0[6];
|
||||
raw_temp / 1000
|
||||
print("Write address\r\n");
|
||||
|
||||
// write_mailbox(8, addr);
|
||||
|
||||
let _ = read_mailbox(8);
|
||||
|
||||
if MBOX.0[1] == 0 {
|
||||
print("Failed\r\n");
|
||||
}
|
||||
let raw_temp = MBOX.0[5];
|
||||
raw_temp
|
||||
}
|
||||
}
|
||||
|
||||
54
src/main.rs
54
src/main.rs
@@ -5,6 +5,7 @@
|
||||
use core::{
|
||||
arch::{asm, global_asm},
|
||||
panic::PanicInfo,
|
||||
ptr::write_volatile,
|
||||
};
|
||||
|
||||
use nova::{
|
||||
@@ -12,18 +13,19 @@ use nova::{
|
||||
mailbox::read_soc_temp,
|
||||
peripherals::{
|
||||
gpio::{
|
||||
gpio_get_state, gpio_high, gpio_low, gpio_pull_up, set_falling_edge_detect,
|
||||
set_gpio_function, GPIOFunction,
|
||||
blink_gpio, gpio_pull_up, set_falling_edge_detect, set_gpio_function, GPIOFunction,
|
||||
},
|
||||
uart::{print, uart_init},
|
||||
uart::{print, print_u32, uart_init},
|
||||
},
|
||||
timer::{delay_nops, sleep_ms, sleep_us},
|
||||
timer::{delay_nops, sleep_us},
|
||||
};
|
||||
|
||||
global_asm!(include_str!("vector.S"));
|
||||
|
||||
extern "C" {
|
||||
fn el2_to_el1();
|
||||
static mut __bss_start: u32;
|
||||
static mut __bss_end: u32;
|
||||
}
|
||||
|
||||
#[panic_handler]
|
||||
@@ -47,6 +49,9 @@ pub unsafe extern "C" fn _start() {
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn main() -> ! {
|
||||
unsafe {
|
||||
zero_bss();
|
||||
}
|
||||
enable_uart();
|
||||
|
||||
// Set ACT Led to Outout
|
||||
@@ -59,14 +64,24 @@ pub extern "C" fn main() -> ! {
|
||||
print("Hello World!\r\n");
|
||||
|
||||
unsafe {
|
||||
asm!("mrs x0, SCTLR_EL1");
|
||||
el2_to_el1();
|
||||
}
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
unsafe fn zero_bss() {
|
||||
let mut bss: *mut u32 = &raw mut __bss_start as *mut u32;
|
||||
while bss < &raw mut __bss_end as *mut u32 {
|
||||
write_volatile(bss, 0);
|
||||
bss = bss.add(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn kernel_main() -> ! {
|
||||
print("AAA\r\n");
|
||||
print_current_el_str();
|
||||
|
||||
sleep_us(500_000);
|
||||
@@ -78,38 +93,13 @@ pub extern "C" fn kernel_main() -> ! {
|
||||
set_falling_edge_detect(26, true);
|
||||
|
||||
loop {
|
||||
//let temp = read_soc_temp();
|
||||
//u32_to_ascii(temp as u8);
|
||||
let temp = read_soc_temp();
|
||||
print_u32(temp);
|
||||
|
||||
let _ = gpio_high(29);
|
||||
|
||||
sleep_ms(500); // 0.5s
|
||||
let _ = gpio_low(29);
|
||||
sleep_ms(500); // 0.5s
|
||||
print_gpio_state();
|
||||
blink_gpio(29, 500);
|
||||
}
|
||||
}
|
||||
|
||||
fn print_gpio_state() {
|
||||
let state = gpio_get_state(26);
|
||||
|
||||
let ascii_byte = b'0' + state;
|
||||
let data = [ascii_byte];
|
||||
|
||||
let s = str::from_utf8(&data).unwrap();
|
||||
print(s);
|
||||
print("\r\n");
|
||||
}
|
||||
|
||||
fn u32_to_ascii(val: u8) {
|
||||
let ascii_byte = b'0' + val;
|
||||
let data = [ascii_byte];
|
||||
|
||||
let s = str::from_utf8(&data).unwrap();
|
||||
print(s);
|
||||
print("C\r\n");
|
||||
}
|
||||
|
||||
pub fn get_current_el() -> u64 {
|
||||
let el: u64;
|
||||
unsafe {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use core::result::Result;
|
||||
use core::result::Result::Ok;
|
||||
|
||||
use crate::timer::delay_nops;
|
||||
use crate::timer::{delay_nops, sleep_ms};
|
||||
use crate::{mmio_read, mmio_write};
|
||||
|
||||
const GPFSEL_BASE: u32 = 0x3F20_0000;
|
||||
@@ -164,3 +164,11 @@ pub fn set_rising_edge_detect(gpio: u8, enable: bool) {
|
||||
|
||||
mmio_write(register_addr, new_val);
|
||||
}
|
||||
|
||||
pub fn blink_gpio(gpio: u8, duration_ms: u32) {
|
||||
let _ = gpio_high(gpio);
|
||||
|
||||
sleep_ms(duration_ms);
|
||||
let _ = gpio_low(gpio);
|
||||
sleep_ms(duration_ms);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use core::{arch::asm, fmt};
|
||||
|
||||
use crate::{mmio_read, mmio_write};
|
||||
|
||||
const BAUD: u32 = 115200;
|
||||
@@ -21,11 +23,34 @@ const UART0_LCRH_FEN: u32 = 1 << 4;
|
||||
/// Print `s` over UART
|
||||
pub fn print(s: &str) {
|
||||
for byte in s.bytes() {
|
||||
while mmio_read(UART0_FR) & UART0_FR_TXFF != 0 {}
|
||||
while (mmio_read(UART0_FR) & UART0_FR_TXFF) != 0 {
|
||||
unsafe { asm!("nop") }
|
||||
}
|
||||
mmio_write(UART0_DR, byte as u32);
|
||||
}
|
||||
// wait till uart is not busy anymore
|
||||
while (mmio_read(UART0_FR) >> 3) & 0b1 != 0 {}
|
||||
while ((mmio_read(UART0_FR) >> 3) & 0b1) != 0 {}
|
||||
}
|
||||
|
||||
pub fn print_u32(mut val: u32) {
|
||||
let mut values = [0u32; 10];
|
||||
for c in &mut values {
|
||||
if val == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
*c = val % 10;
|
||||
val /= 10;
|
||||
}
|
||||
|
||||
for c in values.iter().rev() {
|
||||
let ascii_byte = b'0' + *c as u8;
|
||||
let data = [ascii_byte];
|
||||
|
||||
let s = str::from_utf8(&data).unwrap();
|
||||
print(s);
|
||||
}
|
||||
print("\r\n");
|
||||
}
|
||||
|
||||
/// Initialize UART peripheral
|
||||
|
||||
@@ -14,8 +14,8 @@ vector_table:
|
||||
ventry .
|
||||
ventry .
|
||||
|
||||
ventry .
|
||||
ventry irq_handler // IRQ(Interrupt Request) 0x280
|
||||
ventry synchronous_interrupt // Synchronous Exception 0x200
|
||||
ventry irq_handler // IRQ(Interrupt Request) 0x280
|
||||
ventry .
|
||||
ventry .
|
||||
|
||||
@@ -44,6 +44,11 @@ el2_to_el1:
|
||||
adr x0, vector_table
|
||||
msr VBAR_EL1, x0
|
||||
|
||||
// Disable MMU
|
||||
mrs x0, sctlr_el1
|
||||
bic x0, x0, #1
|
||||
msr sctlr_el1, x0
|
||||
|
||||
isb
|
||||
|
||||
// Return to EL1
|
||||
|
||||
@@ -10,4 +10,5 @@ qemu-system-aarch64 \
|
||||
-serial stdio \
|
||||
-sd ../sd.img \
|
||||
-display none \
|
||||
-kernel ../target/aarch64-unknown-none/debug/kernel8.img
|
||||
-kernel ../target/aarch64-unknown-none/debug/kernel8.img \
|
||||
-s -S
|
||||
|
||||
Reference in New Issue
Block a user