From: Ben Gras Date: Thu, 23 Apr 2009 15:11:16 +0000 (+0000) Subject: set global flag for kernel pages, so tlb entries for kernel aren't thrown X-Git-Tag: v3.1.4~71 X-Git-Url: http://zhaoyanbai.com/repos/Bv9ARM.ch08.html?a=commitdiff_plain;h=ef8a74130121207e7ada0a314b7298711d286508;p=minix.git set global flag for kernel pages, so tlb entries for kernel aren't thrown away on cr3 reload. minor optimization. --- diff --git a/kernel/arch/i386/klib386.s b/kernel/arch/i386/klib386.s index e91bba094..0aff6c0bd 100755 --- a/kernel/arch/i386/klib386.s +++ b/kernel/arch/i386/klib386.s @@ -38,6 +38,8 @@ .define _write_cr3 ! write cr3 .define _last_cr3 .define _write_cr0 ! write a value in cr0 +.define _read_cr4 +.define _write_cr4 .define _kernel_cr3 @@ -606,6 +608,31 @@ _write_cr0: pop ebp ret +!*===========================================================================* +!* read_cr4 * +!*===========================================================================* +! PUBLIC unsigned long read_cr4(void); +_read_cr4: + push ebp + mov ebp, esp +.data1 0x0f, 0x20, 0xe0 ! mov eax, cr4 + pop ebp + ret + +!*===========================================================================* +!* write_cr4 * +!*===========================================================================* +! PUBLIC void write_cr4(unsigned long value); +_write_cr4: + push ebp + mov ebp, esp + mov eax, 8(ebp) +.data1 0x0f, 0x22, 0xe0 ! mov cr4, eax + jmp 0f +0: + pop ebp + ret + !*===========================================================================* !* write_cr3 * !*===========================================================================* diff --git a/kernel/arch/i386/memory.c b/kernel/arch/i386/memory.c index 16c6cb294..7e8456b84 100644 --- a/kernel/arch/i386/memory.c +++ b/kernel/arch/i386/memory.c @@ -149,10 +149,28 @@ PRIVATE void set_cr3() PRIVATE void vm_enable_paging(void) { - u32_t cr0; + u32_t cr0, cr4; + + + cr0= read_cr0(); + cr4= read_cr4(); + + /* First clear PG and PGE flag, as PGE must be enabled after PG. */ + write_cr0(cr0 & ~I386_CR0_PG); + write_cr4(cr4 & ~I386_CR4_PGE); cr0= read_cr0(); + cr4= read_cr4(); + + /* First enable paging, then enable global page flag. */ write_cr0(cr0 | I386_CR0_PG); + write_cr4(cr4 | I386_CR4_PGE); + +{ + u32_t cr4v; + cr4v = read_cr4(); + kprintf("cr4 = 0x%lx\n", cr4v); +} } PUBLIC vir_bytes alloc_remote_segment(u32_t *selector, diff --git a/kernel/arch/i386/proto.h b/kernel/arch/i386/proto.h index de8de011e..b6ae9b27a 100644 --- a/kernel/arch/i386/proto.h +++ b/kernel/arch/i386/proto.h @@ -62,6 +62,8 @@ _PROTOTYPE( void reset, (void) ); _PROTOTYPE( void int86, (void) ); _PROTOTYPE( unsigned long read_cr0, (void) ); _PROTOTYPE( void write_cr0, (unsigned long value) ); +_PROTOTYPE( unsigned long read_cr4, (void) ); +_PROTOTYPE( void write_cr4, (unsigned long value) ); _PROTOTYPE( void write_cr3, (unsigned long value) ); _PROTOTYPE( unsigned long read_cpu_flags, (void) ); _PROTOTYPE( void phys_insb, (U16_t port, phys_bytes buf, size_t count) ); diff --git a/servers/vm/i386/pagetable.c b/servers/vm/i386/pagetable.c index 5c421f471..a9ad925be 100644 --- a/servers/vm/i386/pagetable.c +++ b/servers/vm/i386/pagetable.c @@ -785,12 +785,12 @@ PUBLIC int pt_mapkernel(pt_t *pt) /* Map in text. flags: don't write, supervisor only */ if((r=pt_writemap(pt, KERNEL_TEXT, KERNEL_TEXT, KERNEL_TEXT_LEN, - I386_VM_PRESENT, 0)) != OK) + I386_VM_PRESENT|I386_VM_GLOBAL, 0)) != OK) return r; /* Map in data. flags: read-write, supervisor only */ if((r=pt_writemap(pt, KERNEL_DATA, KERNEL_DATA, KERNEL_DATA_LEN, - I386_VM_PRESENT|I386_VM_WRITE, 0)) != OK) + I386_VM_PRESENT|I386_VM_WRITE|I386_VM_GLOBAL, 0)) != OK) return r; return OK; diff --git a/servers/vm/i386/pagetable.h b/servers/vm/i386/pagetable.h index e4934c72e..b26ac9cd3 100644 --- a/servers/vm/i386/pagetable.h +++ b/servers/vm/i386/pagetable.h @@ -26,12 +26,13 @@ typedef struct { #define PTF_WRITE I386_VM_WRITE #define PTF_PRESENT I386_VM_PRESENT #define PTF_USER I386_VM_USER +#define PTF_GLOBAL I386_VM_GLOBAL #define PTF_MAPALLOC I386_VM_PTAVAIL1 /* Page allocated by pt code. */ /* For arch-specific PT routines to check if no bits outside * the regular flags are set. */ -#define PTF_ALLFLAGS (PTF_WRITE|PTF_PRESENT|PTF_USER) +#define PTF_ALLFLAGS (PTF_WRITE|PTF_PRESENT|PTF_USER|PTF_GLOBAL) #endif