fix runtime error on aarch64

- InactivePageTable::activate should be separated for user & kernel (TTBR1/0)
- disable swappable for aarch64 (bug?)
- use polling getchar as serial interrupt is not implemented
master
WangRunji 6 years ago
parent b5ced136f7
commit acafe19e26

@ -94,7 +94,7 @@ fn handle_syscall(num: u16, tf: &mut TrapFrame) {
fn handle_page_fault(tf: &mut TrapFrame) { fn handle_page_fault(tf: &mut TrapFrame) {
let addr = FAR_EL1.get(); let addr = FAR_EL1.get();
trace!("\nEXCEPTION: Page Fault @ {:#x}", addr); error!("\nEXCEPTION: Page Fault @ {:#x}", addr);
crate::trap::error(tf); crate::trap::error(tf);
} }

@ -109,9 +109,8 @@ fn remap_the_kernel() {
use super::board::{IO_REMAP_BASE, IO_REMAP_END}; use super::board::{IO_REMAP_BASE, IO_REMAP_END};
ms.push(MemoryArea::new_identity(IO_REMAP_BASE, IO_REMAP_END, MemoryAttr::default().mmio(), "io_remap")); ms.push(MemoryArea::new_identity(IO_REMAP_BASE, IO_REMAP_END, MemoryAttr::default().mmio(), "io_remap"));
unsafe { ms.activate(); } unsafe { ms.get_page_table_mut().activate_as_kernel(); }
use core::mem::forget; ::core::mem::forget(ms);
forget(ms);
info!("kernel remap end"); info!("kernel remap end");
} }

@ -224,11 +224,11 @@ impl InactivePageTable for InactivePageTable0 {
} }
unsafe fn activate(&self) { unsafe fn activate(&self) {
let old_frame = ttbr_el1_read(0); let old_frame = ttbr_el1_read(1);
let new_frame = self.p4_frame.clone(); let new_frame = self.p4_frame.clone();
debug!("switch TTBR0 {:?} -> {:?}", old_frame, new_frame); debug!("switch TTBR1 {:?} -> {:?}", old_frame, new_frame);
if old_frame != new_frame { if old_frame != new_frame {
ttbr_el1_write(0, new_frame); ttbr_el1_write(1, new_frame);
tlb_invalidate_all(); tlb_invalidate_all();
} }
} }
@ -275,6 +275,17 @@ impl InactivePageTable0 {
table[KERNEL_PML4].set_frame(Frame::containing_address(e0.addr()), EF::default(), MairNormal::attr_value()); table[KERNEL_PML4].set_frame(Frame::containing_address(e0.addr()), EF::default(), MairNormal::attr_value());
}); });
} }
/// Activate as kernel page table (TTBR0).
/// Used in `arch::memory::remap_the_kernel()`.
pub unsafe fn activate_as_kernel(&self) {
let old_frame = ttbr_el1_read(0);
let new_frame = self.p4_frame.clone();
debug!("switch TTBR0 {:?} -> {:?}", old_frame, new_frame);
if old_frame != new_frame {
ttbr_el1_write(0, new_frame);
tlb_invalidate_all();
}
}
} }
impl Drop for InactivePageTable0 { impl Drop for InactivePageTable0 {

@ -100,12 +100,13 @@ impl Stdin {
pub fn pop(&self) -> char { pub fn pop(&self) -> char {
// QEMU v3.0 don't support M-mode external interrupt (bug?) // QEMU v3.0 don't support M-mode external interrupt (bug?)
// So we have to use polling. // So we have to use polling.
#[cfg(feature = "m_mode")] // TODO: serial interrupt on aarch64
#[cfg(any(feature = "m_mode", target_arch = "aarch64"))]
loop { loop {
let c = crate::arch::io::getchar(); let c = crate::arch::io::getchar();
if c != '\0' { return c; } if c != '\0' { return c; }
} }
#[cfg(not(feature = "m_mode"))] #[cfg(not(any(feature = "m_mode", target_arch = "aarch64")))]
loop { loop {
let ret = self.buf.lock().pop_front(); let ret = self.buf.lock().pop_front();
match ret { match ret {

@ -97,7 +97,6 @@ impl ContextImpl {
let kstack = KernelStack::new(); let kstack = KernelStack::new();
//set the user Memory pages in the memory set swappable //set the user Memory pages in the memory set swappable
#[cfg(not(feature = "no_mmu"))]
memory_set_map_swappable(&mut memory_set); memory_set_map_swappable(&mut memory_set);
Box::new(ContextImpl { Box::new(ContextImpl {
@ -132,7 +131,6 @@ impl ContextImpl {
info!("temporary copy data!"); info!("temporary copy data!");
let kstack = KernelStack::new(); let kstack = KernelStack::new();
#[cfg(not(feature = "no_mmu"))]
memory_set_map_swappable(&mut memory_set); memory_set_map_swappable(&mut memory_set);
info!("FORK() finsihed!"); info!("FORK() finsihed!");
@ -147,6 +145,7 @@ impl ContextImpl {
} }
#[cfg(not(feature = "no_mmu"))] #[cfg(not(feature = "no_mmu"))]
#[cfg(not(target_arch = "aarch64"))]
impl Drop for ContextImpl { impl Drop for ContextImpl {
fn drop(&mut self){ fn drop(&mut self){
info!("come in to drop for ContextImpl"); info!("come in to drop for ContextImpl");
@ -257,8 +256,8 @@ fn memory_attr_from(elf_flags: Flags) -> MemoryAttr {
* @brief: * @brief:
* map the memory area in the memory_set swappalbe, specially for the user process * map the memory area in the memory_set swappalbe, specially for the user process
*/ */
#[cfg(not(feature = "no_mmu"))] #[cfg(not(any(feature = "no_mmu", target_arch = "aarch64")))]
pub fn memory_set_map_swappable(memory_set: &mut MemorySet){ pub fn memory_set_map_swappable(memory_set: &mut MemorySet) {
info!("COME INTO memory set map swappable!"); info!("COME INTO memory set map swappable!");
let pt = unsafe { let pt = unsafe {
memory_set.get_page_table_mut() as *mut InactivePageTable0 memory_set.get_page_table_mut() as *mut InactivePageTable0
@ -272,3 +271,8 @@ pub fn memory_set_map_swappable(memory_set: &mut MemorySet){
info!("Finishing setting pages swappable"); info!("Finishing setting pages swappable");
} }
#[cfg(any(feature = "no_mmu", target_arch = "aarch64"))]
pub fn memory_set_map_swappable(memory_set: &mut MemorySet) {
// FIXME: Page Fault on aarch64
// NOTE: This function may disappear after refactor memory crate
}

@ -27,7 +27,6 @@ pub fn init() {
for i in 0..4 { for i in 0..4 {
manager.add(ContextImpl::new_kernel(idle, i), 0); manager.add(ContextImpl::new_kernel(idle, i), 0);
} }
#[cfg(not(target_arch = "aarch64"))]
crate::shell::run_user_shell(); crate::shell::run_user_shell();
info!("process init end"); info!("process init end");

Loading…
Cancel
Save