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