used in the future for mapping in local APIC memory.
#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 */
_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) \
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));
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;
+}
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 */
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; }
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);
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. */
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);
+}