mirror of
https://github.com/sgmarz/osblog.git
synced 2024-11-23 18:06:20 +04:00
Fixed trap handler, load kernel stack from trap, fixed init, map a larger swath of memory for init.
This commit is contained in:
parent
e6ccf15bda
commit
57145beefd
@ -24,7 +24,6 @@
|
||||
fld f\i, ((NUM_GP_REGS+(\i))*REG_SIZE)(\basereg)
|
||||
.endm
|
||||
|
||||
|
||||
.section .text
|
||||
.global m_trap_vector
|
||||
# This must be aligned by 4 since the last two bits
|
||||
@ -69,8 +68,8 @@ m_trap_vector:
|
||||
csrr a2, mcause
|
||||
csrr a3, mhartid
|
||||
csrr a4, mstatus
|
||||
mv a5, t5
|
||||
ld sp, 520(a5)
|
||||
la t0, KERNEL_STACK_END
|
||||
ld sp, 0(t0)
|
||||
call m_trap
|
||||
|
||||
# When we get here, we've returned from m_trap, restore registers
|
||||
@ -109,6 +108,8 @@ switch_to_user:
|
||||
csrw mstatus, t0
|
||||
csrw mepc, a1
|
||||
csrw satp, a2
|
||||
li t1, 0xaaa
|
||||
csrw mie, t1
|
||||
# This fence forces the MMU to flush the TLB. However, since
|
||||
# we're using the PID as the address space identifier, we might
|
||||
# only need this when we create a process. Right now, this ensures
|
||||
|
@ -140,6 +140,12 @@ extern "C" fn kinit() -> usize {
|
||||
println!("Getting ready for first process.");
|
||||
println!("Issuing the first context-switch timer.");
|
||||
unsafe {
|
||||
cpu::mscratch_write(
|
||||
(&mut cpu::KERNEL_TRAP_FRAME[0]
|
||||
as *mut cpu::TrapFrame)
|
||||
as usize,
|
||||
);
|
||||
cpu::KERNEL_TRAP_FRAME[0].hartid = 0;
|
||||
let mtimecmp = 0x0200_4000 as *mut u64;
|
||||
let mtime = 0x0200_bff8 as *const u64;
|
||||
// The frequency given by QEMU is 10_000_000 Hz, so this sets
|
||||
|
@ -26,7 +26,7 @@ const STACK_PAGES: usize = 2;
|
||||
// regardless of where it is on the kernel heap.
|
||||
const STACK_ADDR: usize = 0xf_0000_0000;
|
||||
// All processes will have a defined starting point in virtual memory.
|
||||
const PROCESS_STARTING_ADDR: usize = 0x2000_0000;
|
||||
const PROCESS_STARTING_ADDR: usize = 0x8000_0000;
|
||||
|
||||
// Here, we store a process list. It uses the global allocator
|
||||
// that we made before and its job is to store all processes.
|
||||
@ -94,6 +94,7 @@ pub fn init() -> usize {
|
||||
// the address, and then move it right back in.
|
||||
let pl = PROCESS_LIST.take().unwrap();
|
||||
let p = pl.front().unwrap().frame;
|
||||
let func_vaddr = pl.front().unwrap().program_counter;
|
||||
let frame = &p as *const TrapFrame as usize;
|
||||
mscratch_write(frame);
|
||||
satp_write(build_satp(
|
||||
@ -107,7 +108,7 @@ pub fn init() -> usize {
|
||||
PROCESS_LIST.replace(pl);
|
||||
// Return the first instruction's address to execute.
|
||||
// Since we use the MMU, all start here.
|
||||
PROCESS_STARTING_ADDR
|
||||
func_vaddr
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,13 +164,15 @@ impl Process {
|
||||
}
|
||||
pub fn new_default(func: fn()) -> Self {
|
||||
let func_addr = func as usize;
|
||||
let func_vaddr = func_addr; //- 0x6000_0000;
|
||||
// println!("func_addr = {:x} -> {:x}", func_addr, func_vaddr);
|
||||
// We will convert NEXT_PID below into an atomic increment when
|
||||
// we start getting into multi-hart processing. For now, we want
|
||||
// a process. Get it to work, then improve it!
|
||||
let mut ret_proc =
|
||||
Process { frame: TrapFrame::zero(),
|
||||
stack: alloc(STACK_PAGES),
|
||||
program_counter: PROCESS_STARTING_ADDR,
|
||||
program_counter: func_vaddr,
|
||||
pid: unsafe { NEXT_PID },
|
||||
root: zalloc(1) as *mut Table,
|
||||
state: ProcessState::Waiting,
|
||||
@ -207,21 +210,17 @@ impl Process {
|
||||
0,
|
||||
);
|
||||
}
|
||||
// Map the program counter on the MMU
|
||||
map(
|
||||
pt,
|
||||
PROCESS_STARTING_ADDR,
|
||||
func_addr,
|
||||
EntryBits::UserReadExecute.val(),
|
||||
0,
|
||||
);
|
||||
map(
|
||||
pt,
|
||||
PROCESS_STARTING_ADDR + 0x1001,
|
||||
func_addr + 0x1001,
|
||||
EntryBits::UserReadExecute.val(),
|
||||
0,
|
||||
);
|
||||
// Map the program counter on the MMU and other bits
|
||||
for i in 0..=100 {
|
||||
let modifier = i * 0x1000;
|
||||
map(
|
||||
pt,
|
||||
func_vaddr + modifier,
|
||||
func_addr + modifier,
|
||||
EntryBits::UserReadWriteExecute.val(),
|
||||
0,
|
||||
);
|
||||
}
|
||||
ret_proc
|
||||
}
|
||||
}
|
||||
|
@ -118,6 +118,7 @@ extern "C" fn m_trap(epc: usize,
|
||||
2 => {
|
||||
// Illegal instruction
|
||||
panic!("Illegal instruction CPU#{} -> 0x{:08x}: 0x{:08x}\n", hart, epc, tval);
|
||||
while true {}
|
||||
},
|
||||
8 => {
|
||||
// Environment (system) call from User mode
|
||||
@ -137,16 +138,19 @@ extern "C" fn m_trap(epc: usize,
|
||||
12 => {
|
||||
// Instruction page fault
|
||||
println!("Instruction page fault CPU#{} -> 0x{:08x}: 0x{:08x}", hart, epc, tval);
|
||||
while true {}
|
||||
return_pc += 4;
|
||||
},
|
||||
13 => {
|
||||
// Load page fault
|
||||
println!("Load page fault CPU#{} -> 0x{:08x}: 0x{:08x}", hart, epc, tval);
|
||||
while true {}
|
||||
return_pc += 4;
|
||||
},
|
||||
15 => {
|
||||
// Store page fault
|
||||
println!("Store page fault CPU#{} -> 0x{:08x}: 0x{:08x}", hart, epc, tval);
|
||||
while true {}
|
||||
return_pc += 4;
|
||||
},
|
||||
_ => {
|
||||
|
Loading…
Reference in New Issue
Block a user