123 lines
4.4 KiB
C
123 lines
4.4 KiB
C
#ifndef MINIOS_MMU_H
|
|
#define MINIOS_MMU_H
|
|
|
|
#include <type.h>
|
|
|
|
// 内核并不是恒等映射
|
|
// 3GB~3GB+128MB的线性地址被映射到0~128MB的物理地址上
|
|
// kernel程序的运行在3GB~3GB+128MB的线性地址上
|
|
// 低3GB线性地址用于存放用户程序
|
|
#define KERNBASE 0xC0000000
|
|
#define K_PHY2LIN(x) ((x)+KERNBASE)
|
|
#define K_LIN2PHY(x) ((x)-KERNBASE)
|
|
|
|
#define KB 1024u
|
|
#define MB (1024u * KB)
|
|
#define GB (1024u * MB)
|
|
|
|
// A linear address 'la' has a three-part structure as follows:
|
|
//
|
|
// +--------10------+-------10-------+---------12----------+
|
|
// | Page Directory | Page Table | Offset within Page |
|
|
// | Index | Index | |
|
|
// +----------------+----------------+---------------------+
|
|
// \--- PDX(la) --/ \--- PTX(la) --/ \---- PGOFF(la) ----/
|
|
// \---------- PGNUM(la) ----------/
|
|
//
|
|
// The PDX, PTX, PGOFF, and PGNUM macros decompose linear addresses as shown.
|
|
// To construct a linear address la from PDX(la), PTX(la), and PGOFF(la),
|
|
// use PGADDR(PDX(la), PTX(la), PGOFF(la)).
|
|
|
|
// page number field of address
|
|
#define PGNUM(la) (((uintptr_t) (la)) >> PTXSHIFT)
|
|
|
|
// page directory index
|
|
#define PDX(la) ((((uintptr_t) (la)) >> PDXSHIFT) & 0x3FF)
|
|
|
|
// page table index
|
|
#define PTX(la) ((((uintptr_t) (la)) >> PTXSHIFT) & 0x3FF)
|
|
|
|
// offset in page
|
|
#define PGOFF(la) (((uintptr_t) (la)) & 0xFFF)
|
|
|
|
// construct linear address from indexes and offset
|
|
#define PGADDR(d, t, o) ((void*) ((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
|
|
|
|
// Page directory and page table constants.
|
|
#define NPDENTRIES 1024 // page directory entries per page directory
|
|
#define NPTENTRIES 1024 // page table entries per page table
|
|
|
|
#define PGSIZE 4096 // bytes mapped by a page
|
|
#define PGSHIFT 12 // log2(PGSIZE)
|
|
|
|
#define PTSIZE (PGSIZE*NPTENTRIES) // bytes mapped by a page directory entry
|
|
#define PTSHIFT 22 // log2(PTSIZE)
|
|
|
|
#define PTXSHIFT 12 // offset of PTX in a linear address
|
|
#define PDXSHIFT 22 // offset of PDX in a linear address
|
|
|
|
// Page table/directory entry flags.
|
|
#define PTE_P 0x001 // Present
|
|
#define PTE_W 0x002 // Writeable
|
|
#define PTE_U 0x004 // User
|
|
#define PTE_PWT 0x008 // Write-Through
|
|
#define PTE_PCD 0x010 // Cache-Disable
|
|
#define PTE_A 0x020 // Accessed
|
|
#define PTE_D 0x040 // Dirty
|
|
#define PTE_PS 0x080 // Page Size
|
|
#define PTE_G 0x100 // Global
|
|
|
|
// Address in page table or page directory entry
|
|
#define PTE_ADDR(pte) ((phyaddr_t) (pte) & ~0xFFF)
|
|
|
|
// Control Register flags
|
|
#define CR0_PE 0x00000001 // Protection Enable
|
|
#define CR0_MP 0x00000002 // Monitor coProcessor
|
|
#define CR0_EM 0x00000004 // Emulation
|
|
#define CR0_TS 0x00000008 // Task Switched
|
|
#define CR0_ET 0x00000010 // Extension Type
|
|
#define CR0_NE 0x00000020 // Numeric Errror
|
|
#define CR0_WP 0x00010000 // Write Protect
|
|
#define CR0_AM 0x00040000 // Alignment Mask
|
|
#define CR0_NW 0x20000000 // Not Writethrough
|
|
#define CR0_CD 0x40000000 // Cache Disable
|
|
#define CR0_PG 0x80000000 // Paging
|
|
|
|
#define CR4_PCE 0x00000100 // Performance counter enable
|
|
#define CR4_MCE 0x00000040 // Machine Check Enable
|
|
#define CR4_PSE 0x00000010 // Page Size Extensions
|
|
#define CR4_DE 0x00000008 // Debugging Extensions
|
|
#define CR4_TSD 0x00000004 // Time Stamp Disable
|
|
#define CR4_PVI 0x00000002 // Protected-Mode Virtual Interrupts
|
|
#define CR4_VME 0x00000001 // V86 Mode Extensions
|
|
|
|
// Eflags register
|
|
#define FL_CF 0x00000001 // Carry Flag
|
|
#define FL_PF 0x00000004 // Parity Flag
|
|
#define FL_AF 0x00000010 // Auxiliary carry Flag
|
|
#define FL_ZF 0x00000040 // Zero Flag
|
|
#define FL_SF 0x00000080 // Sign Flag
|
|
#define FL_TF 0x00000100 // Trap Flag
|
|
#define FL_IF 0x00000200 // Interrupt Flag
|
|
#define FL_DF 0x00000400 // Direction Flag
|
|
#define FL_OF 0x00000800 // Overflow Flag
|
|
#define FL_IOPL_MASK 0x00003000 // I/O Privilege Level bitmask
|
|
#define FL_IOPL_0 0x00000000 // IOPL == 0
|
|
#define FL_IOPL_1 0x00001000 // IOPL == 1
|
|
#define FL_IOPL_2 0x00002000 // IOPL == 2
|
|
#define FL_IOPL_3 0x00003000 // IOPL == 3
|
|
#define FL_NT 0x00004000 // Nested Task
|
|
#define FL_RF 0x00010000 // Resume Flag
|
|
#define FL_VM 0x00020000 // Virtual 8086 mode
|
|
#define FL_AC 0x00040000 // Alignment Check
|
|
#define FL_VIF 0x00080000 // Virtual Interrupt Flag
|
|
#define FL_VIP 0x00100000 // Virtual Interrupt Pending
|
|
#define FL_ID 0x00200000 // ID flag
|
|
|
|
// Page fault error codes
|
|
#define FEC_PR 0x1 // Page fault caused by protection violation
|
|
#define FEC_WR 0x2 // Page fault caused by a write
|
|
#define FEC_U 0x4 // Page fault occured while in user mode
|
|
|
|
|
|
#endif /* MINIOS_MMU_H */ |