From 564f787e916392af7b1960d079abf110234305d4 Mon Sep 17 00:00:00 2001 From: rsc Date: Sun, 16 Jul 2006 16:55:52 +0000 Subject: [PATCH] Eliminate annoying Pseudodesc structure. Eliminate unnecessary parts of mmu.h. --- mmu.h | 100 ++------------------------------------------------------ proc.c | 7 ++-- proc.h | 1 - trap.c | 3 +- types.h | 1 + x86.h | 27 +++++++++++++-- 6 files changed, 32 insertions(+), 107 deletions(-) diff --git a/mmu.h b/mmu.h index b90a9e3..829815d 100644 --- a/mmu.h +++ b/mmu.h @@ -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__ */ diff --git a/proc.c b/proc.c index f24f4f8..4bcd4ab 100644 --- a/proc.c +++ b/proc.c @@ -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 diff --git a/proc.h b/proc.h index 72bdcf3..9353f88 100644 --- a/proc.h +++ b/proc.h @@ -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 diff --git a/trap.c b/trap.c index 74ea864..85d8eef 100644 --- a/trap.c +++ b/trap.c @@ -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 diff --git a/types.h b/types.h index 01989d6..f520c97 100644 --- a/types.h +++ b/types.h @@ -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; diff --git a/x86.h b/x86.h index 6c67df7..a25d875 100644 --- a/x86.h +++ b/x86.h @@ -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