away on cr3 reload. minor optimization.
.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
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 *
!*===========================================================================*
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,
_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) );
/* 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;
#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