mirror of
https://github.com/iceHtwoO/novaOS.git
synced 2026-04-16 20:22:26 +00:00
feat: terminal, start app by ID
This commit is contained in:
@@ -273,7 +273,7 @@ pub fn map_page(
|
||||
let table = unsafe { &mut *table_ptr };
|
||||
|
||||
if !table.0[l3_off].is_invalid() {
|
||||
return Err(NovaError::Paging);
|
||||
return Err(NovaError::Paging("Page already occupied."));
|
||||
}
|
||||
|
||||
table.0[l3_off] = TableEntry::page_descriptor(physical_address, additional_flags);
|
||||
@@ -315,7 +315,7 @@ pub fn map_l2_block(
|
||||
|
||||
// Verify virtual address is available.
|
||||
if !table.0[l2_off].is_invalid() {
|
||||
return Err(NovaError::Paging);
|
||||
return Err(NovaError::Paging("Block already occupied."));
|
||||
}
|
||||
|
||||
let new_entry = TableEntry::block_descriptor(physical_address, additional_flags);
|
||||
@@ -392,7 +392,7 @@ fn next_table(
|
||||
match table.0[offset].value & 0b11 {
|
||||
0 => {
|
||||
if !create_missing {
|
||||
return Err(NovaError::Paging);
|
||||
return Err(NovaError::Paging("No table defined."));
|
||||
}
|
||||
let new_phys_page_table_address = reserve_page();
|
||||
|
||||
@@ -406,7 +406,9 @@ fn next_table(
|
||||
|
||||
Ok(resolve_table_addr(table.0[offset].address()) as *mut PageTable)
|
||||
}
|
||||
1 => Err(NovaError::Paging),
|
||||
1 => Err(NovaError::Paging(
|
||||
"Can't navigate table due to block mapping.",
|
||||
)),
|
||||
3 => Ok(resolve_table_addr(table.0[offset].address()) as *mut PageTable),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ pub fn reserve_page_explicit(physical_address: usize) -> Result<PhysAddr, NovaEr
|
||||
let word_index = page / 64;
|
||||
|
||||
if unsafe { PAGING_BITMAP.bitmap[word_index] } & (1 << (page % 64)) > 0 {
|
||||
return Err(NovaError::Paging);
|
||||
return Err(NovaError::Paging("Page PA already taken."));
|
||||
}
|
||||
|
||||
unsafe { PAGING_BITMAP.bitmap[word_index] |= 1 << (page % 64) };
|
||||
@@ -47,7 +47,7 @@ pub fn reserve_block_explicit(physical_address: usize) -> Result<(), NovaError>
|
||||
for i in 0..L2_BLOCK_BITMAP_WORDS {
|
||||
unsafe {
|
||||
if PAGING_BITMAP.bitmap[(page / 64) + i] != 0 {
|
||||
return Err(NovaError::Paging);
|
||||
return Err(NovaError::Paging("Block PA already taken."));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ use crate::{
|
||||
};
|
||||
use alloc::vec::Vec;
|
||||
use core::arch::asm;
|
||||
use log::error;
|
||||
use nova_error::NovaError;
|
||||
use spin::Mutex;
|
||||
|
||||
pub struct Application {
|
||||
@@ -28,7 +30,7 @@ impl Application {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// TODO: Temporary fix, while kernel and app share some memory regions
|
||||
// TODO: Temporary solution, while kernel and app share some memory regions
|
||||
#[allow(static_mut_refs)]
|
||||
unsafe {
|
||||
let table = &mut *(virtual_address as *mut PageTable);
|
||||
@@ -40,6 +42,13 @@ impl Application {
|
||||
start_addr,
|
||||
}
|
||||
}
|
||||
|
||||
/// Starts an application.
|
||||
///
|
||||
/// `ELR_EL1` -> Exception Link Register (starting virtual address)
|
||||
/// `SPSR_EL1` -> Saved Program State Register (settings for `eret` behaviour)
|
||||
/// `SP_EL0` -> Stack Pointer Register (virtual_address of stack Pointer)
|
||||
/// `TTBR0_EL1` -> Translation Table base Register Register
|
||||
pub fn start(&self) {
|
||||
unsafe {
|
||||
asm!("msr ELR_EL1, {}", in(reg) self.start_addr);
|
||||
@@ -69,14 +78,27 @@ pub fn initialize_app_manager() {
|
||||
let mut guard = APP_MANAGER.lock();
|
||||
guard.apps = Some(Vec::new());
|
||||
}
|
||||
pub fn add_app(app: Application) {
|
||||
|
||||
pub fn add_app(app: Application) -> Result<(), NovaError> {
|
||||
if let Some(app_list) = APP_MANAGER.lock().apps.as_mut() {
|
||||
app_list.push(app);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(NovaError::General("AppManager not initalized."))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_app(index: usize) {
|
||||
if let Some(app_list) = APP_MANAGER.lock().apps.as_mut() {
|
||||
app_list[index].start();
|
||||
pub fn start_app(index: usize) -> Result<(), NovaError> {
|
||||
if let Some(app) = APP_MANAGER
|
||||
.lock()
|
||||
.apps
|
||||
.as_mut()
|
||||
.and_then(|am| am.get(index))
|
||||
{
|
||||
app.start();
|
||||
unreachable!()
|
||||
} else {
|
||||
error!("Unable to start app due to invalid App ID.");
|
||||
Err(NovaError::General("Invalid app id."))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,12 +20,15 @@ unsafe extern "C" fn rust_synchronous_interrupt_imm_lower_aarch64(frame: &mut Tr
|
||||
log_sync_exception();
|
||||
match esr.ec {
|
||||
0b100100 => {
|
||||
warn!("Cause: Data Abort from a lower Exception level");
|
||||
error!("Cause: Data Abort from a lower Exception level");
|
||||
}
|
||||
0b010101 => {
|
||||
debug!("Cause: SVC instruction execution in AArch64");
|
||||
return handle_svc(frame);
|
||||
}
|
||||
0b100010 => {
|
||||
error!("Cause: PC alignment fault.");
|
||||
}
|
||||
_ => {
|
||||
error!("Synchronous interrupt: Unknown Error Code: {:b}", esr.ec);
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ pub extern "C" fn kernel_main() {
|
||||
enable_irq_source(IRQSource::UartInt);
|
||||
|
||||
let app = Application::new(el0 as *const () as usize);
|
||||
add_app(app);
|
||||
add_app(app).unwrap();
|
||||
|
||||
kernel_loop();
|
||||
}
|
||||
|
||||
@@ -38,14 +38,20 @@ impl Terminal {
|
||||
let val = self.input.clone();
|
||||
self.input.clear();
|
||||
|
||||
match val.as_str() {
|
||||
let mut parts = val.split(" ");
|
||||
|
||||
match parts.next().unwrap() {
|
||||
"temp" => {
|
||||
println!("{}", read_soc_temp([0]).unwrap()[1]);
|
||||
}
|
||||
"el0" => unsafe {
|
||||
let i = 69;
|
||||
asm!("", in("x0") i);
|
||||
start_app(0);
|
||||
"app" => unsafe {
|
||||
if let Some(app_id) = parts.next().and_then(|a| a.parse::<usize>().ok()) {
|
||||
let i = 69;
|
||||
asm!("", in("x0") i);
|
||||
let _ = start_app(app_id);
|
||||
} else {
|
||||
println!("App ID not set.");
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
println!("Unknown command: \"{}\"", self.input);
|
||||
|
||||
@@ -5,11 +5,12 @@ use core::prelude::rust_2024::derive;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum NovaError {
|
||||
General(&'static str),
|
||||
Mailbox,
|
||||
HeapFull,
|
||||
EmptyHeapSegmentNotAllowed,
|
||||
Misalignment,
|
||||
InvalidGranularity,
|
||||
Paging,
|
||||
Paging(&'static str),
|
||||
OutOfMeomory,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user