diff --git a/kernel/riscv.h b/kernel/riscv.h index ccf19eb..8fbeadd 100644 --- a/kernel/riscv.h +++ b/kernel/riscv.h @@ -46,25 +46,12 @@ w_mepc(u64 x) // Supervisor Status Register, sstatus -/** Supervisor Previous Privilege */ -#define SSTATUS_SPP (1L << 8) // Previous mode, 1=Supervisor, 0=User +#define SSTATUS_SPP (1L << 8) // Previous mode, 1=Supervisor, 0=User +#define SSTATUS_SPIE (1L << 5) // Supervisor Previous Interrupt Enable +#define SSTATUS_UPIE (1L << 4) // User Previous Interrupt Enable +#define SSTATUS_SIE (1L << 1) // Supervisor Interrupt Enable +#define SSTATUS_UIE (1L << 0) // User Interrupt Enable -/** Supervisor Previous Interrupt Enable */ -#define SSTATUS_SPIE (1L << 5) - -/** User Previous Interrupt Enable */ -#define SSTATUS_UPIE (1L << 4) - -/** Supervisor Interrupt Enable */ -#define SSTATUS_SIE (1L << 1) - -/** User Interrupt Enable */ -#define SSTATUS_UIE (1L << 0) - -/** - * Read the value of the sstatus register. - * (Supervisor Status Register) - */ static inline u64 r_sstatus() { @@ -73,17 +60,13 @@ r_sstatus() return x; } -/** - * Write a value to the sstatus register. - * (Supervisor Status Register) - */ static inline void w_sstatus(u64 x) { asm volatile("csrw sstatus, %0" : : "r"(x)); } -/** Read Suporvisor Interrupt Pending */ +// Supervisor Interrupt Pending static inline u64 r_sip() { @@ -92,26 +75,16 @@ r_sip() return x; } -/** Write Suporvisor Interrupt Pending */ static inline void w_sip(u64 x) { asm volatile("csrw sip, %0" : : "r"(x)); } -/** Supervisor External Interrup Enable */ -#define SIE_SEIE (1L << 9) - -/** Supervisor Timer Interrupt Enable */ -#define SIE_STIE (1L << 5) - -/** Supervisor Software Interrupt Enable */ -#define SIE_SSIE (1L << 1) - -/** - * Read the value of the sie register. - * (Supervisor Interrupt Enable) - */ +// Supervisor Interrupt Enable +#define SIE_SEIE (1L << 9) // external +#define SIE_STIE (1L << 5) // timer +#define SIE_SSIE (1L << 1) // software static inline u64 r_sie() { @@ -120,29 +93,16 @@ r_sie() return x; } -/** - * Write the valie to the sie rgister - * (Supervisor Interrupt Enable) - */ static inline void w_sie(u64 x) { asm volatile("csrw sie, %0" : : "r"(x)); } -/** Machine External Interrupt Enable */ -#define MIE_MEIE (1L << 11) - -/** Machine Timer Interrupt Enable */ -#define MIE_MTIE (1L << 7) - -/** Machine Software Interrupt Enable */ -#define MIE_MSIE (1L << 3) - -/** - * Read the value of the mie register. - * (Machine Interrupt Enable) - */ +// Machine-mode Interrupt Enable +#define MIE_MEIE (1L << 11) // external +#define MIE_MTIE (1L << 7) // timer +#define MIE_MSIE (1L << 3) // software static inline u64 r_mie() { @@ -151,10 +111,6 @@ r_mie() return x; } -/** - * Write the value to the mie register. - * (Machine Interrupt Enable) - */ static inline void w_mie(u64 x) { @@ -164,15 +120,12 @@ w_mie(u64 x) // supervisor exception program counter, holds the // instruction address to which a return from // exception will go. - -/** Write Supervisor Exception Program Counter */ static inline void w_sepc(u64 x) { asm volatile("csrw sepc, %0" : : "r"(x)); } -/** Read Supervisor Exception Program Counter */ static inline u64 r_sepc() { @@ -181,7 +134,7 @@ r_sepc() return x; } -/** Read Machine Exception Delegation */ +// Machine Exception Delegation static inline u64 r_medeleg() { @@ -190,14 +143,13 @@ r_medeleg() return x; } -/** Write Machine Exception Delegation */ static inline void w_medeleg(u64 x) { asm volatile("csrw medeleg, %0" : : "r"(x)); } -/** Read Machine Interrupt Delegation */ +// Machine Interrupt Delegation static inline u64 r_mideleg() { @@ -206,21 +158,20 @@ r_mideleg() return x; } -/** Write Machine Interrupt Delegation */ static inline void w_mideleg(u64 x) { asm volatile("csrw mideleg, %0" : : "r"(x)); } -/** Write Supervisor Trap-Vector Base Address */ +// Supervisor Trap-Vector Base Address +// low two bits are mode. static inline void w_stvec(u64 x) { asm volatile("csrw stvec, %0" : : "r"(x)); } -/** Read Supervisor Trap-Vector Base Address */ static inline u64 r_stvec() { @@ -229,50 +180,39 @@ r_stvec() return x; } -/** Write Machine Trap-Vector Base Address */ +// Machine-mode interrupt vector static inline void w_mtvec(u64 x) { asm volatile("csrw mtvec, %0" : : "r"(x)); } -/** Read Physical Memory Protection Configuration */ +// Physical Memory Protection static inline void w_pmpcfg0(u64 x) { asm volatile("csrw pmpcfg0, %0" : : "r"(x)); } -/** Write Physical Memory Protection Configuration */ static inline void w_pmpaddr0(u64 x) { asm volatile("csrw pmpaddr0, %0" : : "r"(x)); } -/** Risc-v's sv39 page table scheme. */ +// use riscv's sv39 page table scheme. #define SATP_SV39 (8L << 60) -/** Make Supervisor Address Translation and Protection */ #define MAKE_SATP(pagetable) (SATP_SV39 | (((u64)pagetable) >> 12)) -/** - * Write the value to the satp register. - * (Supervisor Address Translation and Protection) - * - * This register holds the address of the page table. - */ +// supervisor address translation and protection; +// holds the address of the page table. static inline void w_satp(u64 x) { asm volatile("csrw satp, %0" : : "r"(x)); } -/** - * Read the value of the satp register. - * (Supervisor Address Translation and Protection) - * Returns the address of the page table. - */ static inline u64 r_satp() { @@ -281,14 +221,13 @@ r_satp() return x; } -/** Read Supervisor Scratch Register */ static inline void w_mscratch(u64 x) { asm volatile("csrw mscratch, %0" : : "r"(x)); } -/** Supervisor Trap Cause */ +// Supervisor Trap Cause static inline u64 r_scause() { @@ -297,7 +236,7 @@ r_scause() return x; } -/** Supervisor Trap Value */ +// Supervisor Trap Value static inline u64 r_stval() { @@ -306,14 +245,13 @@ r_stval() return x; } -/** Write Machine-mode Counter-Enable Register */ +// Machine-mode Counter-Enable static inline void w_mcounteren(u64 x) { asm volatile("csrw mcounteren, %0" : : "r"(x)); } -/** Read Machine-mode Counter-Enable Register */ static inline u64 r_mcounteren() { @@ -322,10 +260,7 @@ r_mcounteren() return x; } -/** - * Machine-mode cycle counter - * Reports the current wall-clock time from the timer device. - */ +// machine-mode cycle counter static inline u64 r_time() { @@ -334,21 +269,21 @@ r_time() return x; } -/** Enable device interrupts */ +// enable device interrupts static inline void intr_on() { w_sstatus(r_sstatus() | SSTATUS_SIE); } -/** Disable device interrupts */ +// disable device interrupts static inline void intr_off() { w_sstatus(r_sstatus() & ~SSTATUS_SIE); } -/** Are device interrupts enabled? */ +// are device interrupts enabled? static inline int intr_get() { @@ -356,7 +291,6 @@ intr_get() return (x & SSTATUS_SIE) != 0; } -/** Read stack pointer */ static inline u64 r_sp() { @@ -367,8 +301,6 @@ r_sp() // read and write tp, the thread pointer, which xv6 uses to hold // this core's hartid (core number), the index into cpus[]. - -/** Read thread pointer */ static inline u64 r_tp() { @@ -377,14 +309,12 @@ r_tp() return x; } -/** Write thread pointer */ static inline void w_tp(u64 x) { asm volatile("mv tp, %0" : : "r"(x)); } -/** Read the return address */ static inline u64 r_ra() { @@ -393,7 +323,7 @@ r_ra() return x; } -/** Flush the TLB (Translation Lookaside Buffer) */ +// flush the TLB. static inline void sfence_vma() { @@ -401,65 +331,37 @@ sfence_vma() asm volatile("sfence.vma zero, zero"); } -/** Page Table Entry Type */ -typedef u64 pte_t; - -/** Page Table Type */ +typedef u64 pte_t; typedef u64 *pagetable_t; // 512 PTEs #endif // __ASSEMBLER__ -/** Page Size */ -#define PGSIZE 4096 // bytes per page - -/** Page Shift, bits of offset within a page */ -#define PGSHIFT 12 +#define PGSIZE 4096 // bytes per page +#define PGSHIFT 12 // bits of offset within a page #define PGROUNDUP(sz) (((sz) + PGSIZE - 1) & ~(PGSIZE - 1)) #define PGROUNDDOWN(a) (((a)) & ~(PGSIZE - 1)) -/** - * Page Table Entry Flags - */ +#define PTE_V (1L << 0) // valid +#define PTE_R (1L << 1) +#define PTE_W (1L << 2) +#define PTE_X (1L << 3) +#define PTE_U (1L << 4) // user can access -#define PTE_V (1L << 0) /** PTE Valid */ -#define PTE_R (1L << 1) /** PTE Readable */ -#define PTE_W (1L << 2) /** PTE Writeable */ -#define PTE_X (1L << 3) /** PTE Executable */ -#define PTE_U (1L << 4) /** PTE User Accessible */ - -/** - * Helper macros to shift a physical address - * to the right place for a PTE. - */ - -/** Physical Address to Page Table Entry */ +// shift a physical address to the right place for a PTE. #define PA2PTE(pa) ((((u64)pa) >> 12) << 10) -/** Page Table Entry to Physical Address */ #define PTE2PA(pte) (((pte) >> 10) << 12) -/** Page Table Entry Flags */ #define PTE_FLAGS(pte) ((pte) & 0x3FF) -/** - * Helper macros to extract the three 9-bit - * page table indices from a virtual address. - */ - -/** Page Extract Mask */ -#define PXMASK 0x1FF // 9 bits, 0b111111111 - -/** Page Extract Shift */ +// extract the three 9-bit page table indices from a virtual address. +#define PXMASK 0x1FF // 9 bits #define PXSHIFT(level) (PGSHIFT + (9 * (level))) +#define PX(level, va) ((((u64)(va)) >> PXSHIFT(level)) & PXMASK) -/** Page Extract */ -#define PX(level, va) ((((u64)(va)) >> PXSHIFT(level)) & PXMASK) - -/** - * One beyond the highest possible virtual address. - * MAXVA is actually one bit less than the max allowed by - * Sv39, to avoid having to sign-extend virtual addresses - * that have the high bit set. - */ +// one beyond the highest possible virtual address. +// MAXVA is actually one bit less than the max allowed by +// Sv39, to avoid having to sign-extend virtual addresses +// that have the high bit set. #define MAXVA (1L << (9 + 9 + 9 + 12 - 1)) diff --git a/kernel/trampoline.S b/kernel/trampoline.S index 201cd4a..3f514dd 100644 --- a/kernel/trampoline.S +++ b/kernel/trampoline.S @@ -31,16 +31,13 @@ uservec: # save user a0 in sscratch so # a0 can be used to get at TRAPFRAME. - # CSRW = Control and Status Register Write - csrw sscratch, a0 # Save the userspace a0 in sscratch + csrw sscratch, a0 # each process has a separate p->trapframe memory area, # but it's mapped to the same virtual address # (TRAPFRAME) in every process's user page table. li a0, TRAPFRAME - # INFO: To see the layout of TRAPFRAME, see: proc.h - # save the user registers in TRAPFRAME sd ra, 40(a0) sd sp, 48(a0) @@ -51,7 +48,6 @@ uservec: sd t2, 88(a0) sd s0, 96(a0) sd s1, 104(a0) - // Note that we dont save a0 sd a1, 120(a0) sd a2, 128(a0) sd a3, 136(a0) @@ -75,9 +71,8 @@ uservec: sd t6, 280(a0) # save the user a0 in p->trapframe->a0 - # CSRR = Control and Status Register Read - csrr t0, sscratch # Get the userspace a0 from where we stored it before - sd t0, 112(a0) # Store userspace a0 in p->trapframe->a0 + csrr t0, sscratch + sd t0, 112(a0) # initialize kernel stack pointer, from p->trapframe->kernel_sp ld sp, 8(a0) @@ -88,6 +83,7 @@ uservec: # load the address of usertrap(), from p->trapframe->kernel_trap ld t0, 16(a0) + # fetch the kernel page table address, from p->trapframe->kernel_satp. ld t1, 0(a0) @@ -98,7 +94,7 @@ uservec: # install the kernel page table. csrw satp, t1 - # flush now-stale user entries from the TLB (Translation Lookaside Buffer) + # flush now-stale user entries from the TLB. sfence.vma zero, zero # jump to usertrap(), which does not return diff --git a/user/user.ld b/user/user.ld index 20054dc..0ca922b 100644 --- a/user/user.ld +++ b/user/user.ld @@ -5,7 +5,7 @@ ENTRY( _main ) SECTIONS { . = 0x0; - + .text : { *(.text .text.*) }