diff options
| -rw-r--r-- | mmu.h | 100 | ||||
| -rw-r--r-- | proc.c | 7 | ||||
| -rw-r--r-- | proc.h | 1 | ||||
| -rw-r--r-- | trap.c | 3 | ||||
| -rw-r--r-- | types.h | 1 | ||||
| -rw-r--r-- | x86.h | 27 | 
6 files changed, 32 insertions, 107 deletions
| @@ -5,95 +5,10 @@   */  /* - * - *	Part 1.  Paging data structures and constants. - * + *	Register flags and fundamental constants.   */ -// 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) ----/ -//  \----------- PPN(la) -----------/ -// -// The PDX, PTX, PGOFF, and PPN 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 PPN(la)		(((uintptr_t) (la)) >> PTXSHIFT) -#define VPN(la)		PPN(la)		// used to index into vpt[] - -// page directory index -#define PDX(la)		((((uintptr_t) (la)) >> PDXSHIFT) & 0x3FF) -#define VPD(la)		PDX(la)		// used to index into vpd[] - -// 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_MBZ		0x180	// Bits must be zero - -// The PTE_AVAIL bits aren't used by the kernel or interpreted by the -// hardware, so user processes are allowed to set them arbitrarily. -#define PTE_AVAIL	0xE00	// Available for software use - -// Only flags in PTE_USER may be used in system calls. -#define PTE_USER	(PTE_AVAIL | PTE_P | PTE_W | PTE_U) - -// address in page table entry -#define PTE_ADDR(pte)	((physaddr_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 @@ -123,10 +38,9 @@  #define FEC_WR		0x2	// Page fault caused by a write  #define FEC_U		0x4	// Page fault occured while in user mode -  /*   * - *	Part 2.  Segmentation data structures and constants. + *	Segmentation data structures and constants.   *   */ @@ -202,7 +116,7 @@ struct Segdesc {  /*   * - *	Part 3.  Traps. + *	Traps.   *   */ @@ -296,13 +210,5 @@ struct Gatedesc {  	(gate).off_31_16 = (uint32_t) (off) >> 16;		\  } -// Pseudo-descriptors used for LGDT, LLDT and LIDT instructions. -struct Pseudodesc { -	uint16_t _garbage;         // LGDT supposed to be from address 4N+2 -	uint16_t lim;              // Limit -	uint32_t base __attribute__ ((packed));       // Base address -}; -#define PD_ADDR(desc)	(&(desc).pd_lim) -  #endif /* !__ASSEMBLER__ */ @@ -38,9 +38,6 @@ setupsegs(struct proc *p)    p->gdt[SEG_TSS].s = 0;    p->gdt[SEG_UCODE] = SEG(STA_X|STA_R, (unsigned)p->mem, p->sz, 3);    p->gdt[SEG_UDATA] = SEG(STA_W, (unsigned)p->mem, p->sz, 3); -  p->gdt_pd._garbage = 0; -  p->gdt_pd.lim = sizeof(p->gdt) - 1; -  p->gdt_pd.base = (unsigned) p->gdt;  }  // Look in the process table for an UNUSED proc. @@ -159,7 +156,9 @@ scheduler(void)        // to confine all the inline assembly.        // XXX probably ought to lgdt on trap return too, in case        // a system call has moved a program or changed its size. -      asm volatile("lgdt %0" : : "g" (p->gdt_pd.lim)); +      lgdt(p->gdt, sizeof p->gdt); +    // asm volatile("lgdt %0" : : "g" (p->gdt_pd.lim)); +        ltr(SEG_TSS << 3);        // Switch to chosen process.  It is the process's job  @@ -50,7 +50,6 @@ struct proc{    struct Taskstate ts;  // only to give cpu address of kernel stack    struct Segdesc gdt[NSEGS]; -  struct Pseudodesc gdt_pd;    unsigned esp; // kernel stack pointer    unsigned ebp; // kernel frame pointer @@ -8,7 +8,6 @@  #include "syscall.h"  struct Gatedesc idt[256]; -struct Pseudodesc idt_pd = { 0, sizeof(idt) - 1, (unsigned) &idt };  extern unsigned vectors[]; /* vectors.S, array of 256 entry point addresses */  extern void trapenter(); @@ -28,7 +27,7 @@ tvinit()  void  idtinit()  { -  asm volatile("lidt %0" : : "g" (idt_pd.lim)); +  lidt(idt, sizeof idt);  }  void @@ -4,3 +4,4 @@ typedef unsigned short uint16_t;  typedef unsigned char uint8_t;  typedef uint32_t uintptr_t;  typedef uint32_t physaddr_t; +typedef unsigned int uint; @@ -12,7 +12,10 @@ static __inline void outsw(int port, const void *addr, int cnt) __attribute__((a  static __inline void outsl(int port, const void *addr, int cnt) __attribute__((always_inline));  static __inline void outl(int port, uint32_t data) __attribute__((always_inline));  static __inline void invlpg(void *addr) __attribute__((always_inline)); -static __inline void lidt(void *p) __attribute__((always_inline)); +struct Segdesc; +static __inline void lgdt(struct Segdesc *p, int) __attribute__((always_inline)); +struct Gatedesc; +static __inline void lidt(struct Gatedesc *p, int) __attribute__((always_inline));  static __inline void lldt(uint16_t sel) __attribute__((always_inline));  static __inline void ltr(uint16_t sel) __attribute__((always_inline));  static __inline void lcr0(uint32_t val) __attribute__((always_inline)); @@ -141,9 +144,27 @@ invlpg(void *addr)  }    static __inline void -lidt(void *p) +lgdt(struct Segdesc *p, int size)  { -	__asm __volatile("lidt (%0)" : : "r" (p)); +	volatile uint16_t pd[3]; +   +	pd[0] = size-1; +	pd[1] = (uint)p; +	pd[2] = (uint)p >> 16; + +	asm volatile("lgdt (%0)" : : "g" (pd)); +} + +static __inline void +lidt(struct Gatedesc *p, int size) +{ +	volatile uint16_t pd[3]; +   +	pd[0] = size-1; +	pd[1] = (uint)p; +	pd[2] = (uint)p >> 16; +   +	asm volatile("lidt (%0)" : : "g" (pd));  }  static __inline void | 
