]> Zhao Yanbai Git Server - minix.git/commitdiff
allow kernel to tell VM extra physical addresses it wants mapped in.
authorTomas Hruby <tom@minix3.org>
Wed, 11 Nov 2009 12:07:06 +0000 (12:07 +0000)
committerTomas Hruby <tom@minix3.org>
Wed, 11 Nov 2009 12:07:06 +0000 (12:07 +0000)
used in the future for mapping in local APIC memory.

include/minix/com.h
include/minix/syslib.h
kernel/arch/i386/memory.c
kernel/proto.h
kernel/system/do_vmctl.c
lib/syslib/sys_vmctl.c

index cc9ad08757370f84e9cbb5f9f464917c340bfd7c..76918419474a0857752d2c3661f7f1b56eb00b6d 100644 (file)
 #define SVMCTL_MRG_WRITE       m1_i2   /* MEMREQ_GET reply: writeflag */
 #define SVMCTL_MRG_EP          m1_i3   /* MEMREQ_GET reply: process */
 #define SVMCTL_MRG_REQUESTOR   m1_p2   /* MEMREQ_GET reply: requestor */
+#define SVMCTL_MAP_VIR_ADDR    m1_p1
+
+/* Reply message for VMCTL_KERN_PHYSMAP */
+#define SVMCTL_MAP_FLAGS       m2_i1   /* VMMF_* */
+#define SVMCTL_MAP_PHYS_ADDR   m2_l1
+#define SVMCTL_MAP_PHYS_LEN    m2_l2
+
+#define VMMF_UNCACHED          (1L << 0)
 
 /* Codes and field names for SYS_SYSCTL. */
 #define SYSCTL_CODE            m1_i1   /* SYSCTL_CODE_* below */
 #define VMCTL_ENABLE_PAGING    24
 #define VMCTL_I386_INVLPG      25
 #define VMCTL_FLUSHTLB         26
+#define VMCTL_KERN_PHYSMAP     27
+#define VMCTL_KERN_MAP_REPLY   28
 
 /* Field names for SYS_VTIMER. */
 #define VT_WHICH       m2_i1   /* which timer to set/retrieve */
index 5615c63721bedb71d6e5dc86bc0371d1b222d7fc..93aeaf3c03c9715708edf557fdfb043e56ffcaa2 100644 (file)
@@ -68,6 +68,9 @@ _PROTOTYPE( int sys_readbios, (phys_bytes address, void *buf, size_t size));
 _PROTOTYPE( int sys_stime, (time_t boottime));
 _PROTOTYPE( int sys_sysctl, (int ctl, char *arg1, int arg2));
 _PROTOTYPE( int sys_sysctl_stacktrace, (endpoint_t who));
+_PROTOTYPE( int sys_vmctl_get_mapping, (int index, phys_bytes *addr,
+       phys_bytes *len, int *flags));
+_PROTOTYPE( int sys_vmctl_reply_mapping, (int index, vir_bytes addr));
 
 /* Shorthands for sys_sdevio() system call. */
 #define sys_insb(port, proc_ep, buffer, count) \
index fa68ecd36133015effa5c3db237e16d215030343..6eeb659c3693d230ce8a50ee27f922281711f082 100644 (file)
@@ -715,7 +715,7 @@ void vm_print(u32_t *root)
 
        printf("page table 0x%lx:\n", root);
 
-       for(pde = 10; pde < I386_VM_DIR_ENTRIES; pde++) {
+       for(pde = 0; pde < I386_VM_DIR_ENTRIES; pde++) {
                u32_t pde_v;
                u32_t *pte_a;
                pde_v = phys_get32((u32_t) (root + pde));
@@ -1028,3 +1028,19 @@ void i386_freepde(int pde)
                return;
        freepdes[nfreepdes++] = pde;
 }
+
+PUBLIC arch_phys_map(int index, phys_bytes *addr, phys_bytes *len, int *flags)
+{
+       /* we don't want anything */
+       return EINVAL;
+}
+
+PUBLIC arch_phys_map_reply(int index, vir_bytes addr)
+{
+       return OK;
+}
+
+PUBLIC int arch_enable_paging(void)
+{
+       return OK;
+}
index b442fe4dad6733bca7e0279ed5842972dcaaeddc..d52d8ca93b26022d31ccd2c93ab992ea39781a7e 100644 (file)
@@ -161,5 +161,9 @@ _PROTOTYPE( int vm_suspend, (struct proc *caller, struct proc *target,
        phys_bytes lin, phys_bytes size, int wrflag, int type));
 _PROTOTYPE( int delivermsg, (struct proc *target));
 _PROTOTYPE( void arch_do_syscall, (struct proc *proc)                  );
+_PROTOTYPE( int arch_phys_map, (int index, phys_bytes *addr,
+       phys_bytes *len, int *flags));
+_PROTOTYPE( int arch_phys_map_reply, (int index, vir_bytes addr));
+_PROTOTYPE( int arch_enable_paging, (void));
 
 #endif /* PROTO_H */
index 1a358cdbc3b9454085b7b04b62ce94b0d85c2b98..6f7f9f426999873a7445d4cdba1e607aa1cc3b6f 100644 (file)
@@ -22,6 +22,7 @@ register message *m_ptr;      /* pointer to request message */
   int proc_nr, i;
   endpoint_t ep = m_ptr->SVMCTL_WHO;
   struct proc *p, *rp, *target;
+  int err;
 
   if(ep == SELF) { ep = m_ptr->m_source; }
 
@@ -119,6 +120,11 @@ register message *m_ptr;   /* pointer to request message */
 
                return OK;
        case VMCTL_ENABLE_PAGING:
+               /*
+                * system task must not get preempted while switching to paging,
+                * interrupt handling is not safe
+                */
+               lock;
                if(vm_running) 
                        minix_panic("do_vmctl: paging already enabled", NO_NUM);
                vm_init(p);
@@ -126,11 +132,29 @@ register message *m_ptr;  /* pointer to request message */
                        minix_panic("do_vmctl: paging enabling failed", NO_NUM);
                vmassert(p->p_delivermsg_lin ==
                  umap_local(p, D, p->p_delivermsg_vir, sizeof(message)));
+               if ((err = arch_enable_paging()) != OK) {
+                       unlock;
+                       return err;
+               }
                if(newmap(p, (struct mem_map *) m_ptr->SVMCTL_VALUE) != OK)
                        minix_panic("do_vmctl: newmap failed", NO_NUM);
                FIXLINMSG(p);
                vmassert(p->p_delivermsg_lin);
+               unlock;
                return OK;
+       case VMCTL_KERN_PHYSMAP:
+       {
+               int i = m_ptr->SVMCTL_VALUE;
+               return arch_phys_map(i,
+                       (phys_bytes *) &m_ptr->SVMCTL_MAP_PHYS_ADDR,
+                       (phys_bytes *) &m_ptr->SVMCTL_MAP_PHYS_LEN,
+                       &m_ptr->SVMCTL_MAP_FLAGS);
+       }
+       case VMCTL_KERN_MAP_REPLY:
+       {
+               return arch_phys_map_reply(m_ptr->SVMCTL_VALUE,
+                       (vir_bytes) m_ptr->SVMCTL_MAP_VIR_ADDR);
+       }
   }
 
   /* Try architecture-specific vmctls. */
index 29f27e2438f5b6c0f313505dca946292ef52004e..5e93bace5eb386cdd5845f513a913e862b334e11 100644 (file)
@@ -69,3 +69,38 @@ PUBLIC int sys_vmctl_enable_paging(struct mem_map *map)
        m.SVMCTL_VALUE = (int) map;
        return _taskcall(SYSTASK, SYS_VMCTL, &m);
 }
+
+PUBLIC int sys_vmctl_get_mapping(int index,
+       phys_bytes *addr, phys_bytes *len, int *flags)
+{
+       int r;
+       message m;
+
+       m.SVMCTL_WHO = SELF;
+       m.SVMCTL_PARAM = VMCTL_KERN_PHYSMAP;
+       m.SVMCTL_VALUE = (int) index;
+
+       r = _taskcall(SYSTASK, SYS_VMCTL, &m);
+
+       if(r != OK)
+               return r;
+
+       *addr = m.SVMCTL_MAP_PHYS_ADDR;
+       *len = m.SVMCTL_MAP_PHYS_LEN;
+       *flags = m.SVMCTL_MAP_FLAGS;
+
+       return OK;
+}
+
+PUBLIC int sys_vmctl_reply_mapping(int index, vir_bytes addr)
+{
+       int r;
+       message m;
+
+       m.SVMCTL_WHO = SELF;
+       m.SVMCTL_PARAM = VMCTL_KERN_MAP_REPLY;
+       m.SVMCTL_VALUE = index;
+       m.SVMCTL_MAP_VIR_ADDR = (char *) addr;
+
+       return _taskcall(SYSTASK, SYS_VMCTL, &m);
+}