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) {
let addr = FAR_EL1.get();
trace!("\nEXCEPTION: Page Fault @ {:#x}", addr);
error!("\nEXCEPTION: Page Fault @ {:#x}", addr);
crate::trap::error(tf);
}

@ -109,9 +109,8 @@ fn remap_the_kernel() {
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"));
unsafe { ms.activate(); }
use core::mem::forget;
forget(ms);
unsafe { ms.get_page_table_mut().activate_as_kernel(); }
::core::mem::forget(ms);
info!("kernel remap end");
}

@ -224,11 +224,11 @@ impl InactivePageTable for InactivePageTable0 {
}
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();
debug!("switch TTBR0 {:?} -> {:?}", old_frame, new_frame);
debug!("switch TTBR1 {:?} -> {:?}", old_frame, new_frame);
if old_frame != new_frame {
ttbr_el1_write(0, new_frame);
ttbr_el1_write(1, new_frame);
tlb_invalidate_all();
}
}
@ -275,6 +275,17 @@ impl InactivePageTable0 {
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 {

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

@ -97,7 +97,6 @@ impl ContextImpl {
let kstack = KernelStack::new();
//set the user Memory pages in the memory set swappable
#[cfg(not(feature = "no_mmu"))]
memory_set_map_swappable(&mut memory_set);
Box::new(ContextImpl {
@ -132,7 +131,6 @@ impl ContextImpl {
info!("temporary copy data!");
let kstack = KernelStack::new();
#[cfg(not(feature = "no_mmu"))]
memory_set_map_swappable(&mut memory_set);
info!("FORK() finsihed!");
@ -147,6 +145,7 @@ impl ContextImpl {
}
#[cfg(not(feature = "no_mmu"))]
#[cfg(not(target_arch = "aarch64"))]
impl Drop for ContextImpl {
fn drop(&mut self){
info!("come in to drop for ContextImpl");
@ -257,8 +256,8 @@ fn memory_attr_from(elf_flags: Flags) -> MemoryAttr {
* @brief:
* map the memory area in the memory_set swappalbe, specially for the user process
*/
#[cfg(not(feature = "no_mmu"))]
pub fn memory_set_map_swappable(memory_set: &mut MemorySet){
#[cfg(not(any(feature = "no_mmu", target_arch = "aarch64")))]
pub fn memory_set_map_swappable(memory_set: &mut MemorySet) {
info!("COME INTO memory set map swappable!");
let pt = unsafe {
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");
}
#[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 {
manager.add(ContextImpl::new_kernel(idle, i), 0);
}
#[cfg(not(target_arch = "aarch64"))]
crate::shell::run_user_shell();
info!("process init end");

Loading…
Cancel
Save