.globl _getcr3val
.globl _write_cr0 /* write a value in cr0 */
.globl _read_cr3
+.globl _write_cr3
.globl _read_cr4
.globl _write_cr4
0:
pop %ebp
ret
+
+/*===========================================================================*/
+/* write_cr3 */
+/*===========================================================================*/
+/* PUBLIC void write_cr3(unsigned long value); */
+_write_cr3:
+ push %ebp
+ mov %esp, %ebp
+ mov 8(%ebp), %eax
+
+ /* DO NOT CHANGE THE OPERAND!!! gas2ack does not handle it yet */
+ mov %eax, %cr3
+
+ pop %ebp
+ ret
+
/*===========================================================================*/
/* getcr3val */
/*===========================================================================*/
{
if(vm_running)
panic("vm_init: vm_running");
+
+ /* switch_address_space() checks what is in cr3, and doesn't do
+ * anything if it's the same as the cr3 of its argument, newptproc.
+ * If MINIX was previously booted, this could very well be the case.
+ *
+ * The first time switch_address_space() is called, we want to
+ * force it to do something (load cr3 and set newptproc), so we
+ * zero cr3, and force paging off to make that a safe thing to do.
+ *
+ * After that, vm_enable_paging() enables paging with the page table
+ * of newptproc loaded.
+ */
+
+ vm_stop();
+ write_cr3(0);
switch_address_space(newptproc);
assert(ptproc == newptproc);
vm_enable_paging();
vm_running = 1;
-
}
/* This function sets up a mapping from within the kernel's address
return str;
}
+PUBLIC void vm_stop(void)
+{
+ write_cr0(read_cr0() & ~I386_CR0_PG);
+}
+
PRIVATE void vm_enable_paging(void)
{
u32_t cr0, cr4;
_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) );
_PROTOTYPE( void phys_insw, (u16_t port, phys_bytes buf, size_t count) );
endpoint_t to, vir_bytes to_addr, size_t bytes));
_PROTOTYPE( void alloc_segments, (struct proc *rp) );
_PROTOTYPE( void vm_init, (struct proc *first) );
+_PROTOTYPE( void vm_stop, (void) );
_PROTOTYPE( phys_bytes umap_local, (register struct proc *rp, int seg,
vir_bytes vir_addr, vir_bytes bytes));
_PROTOTYPE( phys_bytes umap_remote, (const struct proc* rp, int seg,