code: 9ferno

Download patch

ref: 16593a0c2e42518ea48f64b0c3097e9c71eaf0ae
parent: a1b177116747ff22cceea2121bf40da526ba60c3
author: 9ferno <gophone2015@gmail.com>
date: Tue Aug 10 10:41:19 EDT 2021

working vmap()

--- a/os/pc64/mem.h
+++ b/os/pc64/mem.h
@@ -51,6 +51,7 @@
  */
 #define KDZERO		(0x100000)
 #define KTZERO		(0x200000)
+#define VMAPSIZE  (512ull*GiB)
 
 /*
  * Fundamental addresses
--- a/os/pc64/memory.c
+++ b/os/pc64/memory.c
@@ -6,7 +6,16 @@
 #include "io.h"
 #include "ureg.h"
 
-#define DP if(1){}else print
+/*
+memory.c identify memory from bios, e820
+	puts memory entries to memmap -> conf.mem[] -> xlist.hole's
+	the kernel low level page allocator allocates from the xlist holes (xspanalloc)
+	inferno's meminit() identifies all memory
+	9front splits memory initialization to meminit0() and meminit().
+		after meminit0(), it runs archinit() to ensure architecture specific memory
+		initialization is accounted for.
+ */
+#define DP if(0){}else print
 
 enum {
 	MemUPA		= 0,	/* unbacked physical address */
@@ -43,7 +52,7 @@
 }
 
 static void
-mapkzero(uintptr base, u64 len, int type)
+mapkzero(uintptr base, uintptr len, int type)
 {
 	uintptr flags, n;
 
@@ -61,10 +70,10 @@
 	case MemRAM:
 		if(base < MemMin)
 			return;
-		flags = PTEWRITE|PTEVALID;
+		flags = PTEGLOBAL|PTEWRITE|PTEVALID;
 		break;
 	case MemUMB:
-		flags = PTEWRITE|PTEUNCACHED|PTEVALID;
+		flags = PTEGLOBAL|PTEWRITE|PTEUNCACHED|PTEVALID;
 		break;
 	}
 	pmap(base, flags, len);
@@ -271,23 +280,25 @@
  * does not map the physical address into virtual memory.
  * Call vmap to do that.
  */
-u64
-upaalloc(u64 pa, u32 size, u32 align)
+uintptr
+upaalloc(uintptr pa, u32 size, u32 align)
 {
 	DP("before memmapalloc pa 0x%p size 0x%x %d\n",
 		pa, size, size);
-	// memmapdump();
+	memmapdump();
 	return memmapalloc(pa, size, align, MemUPA);
 }
 
-u64
-upamalloc(u64 pa, u32 size, u32 align)
+uintptr
+upamalloc(uintptr pa, u32 size, u32 align)
 {
+	print("before memmapalloc pa 0x%p size 0x%x %d\n",
+		pa, size, size);
 	return memmapalloc(pa, size, align, MemUPA);
 }
 
-u64
-upaallocwin(u64 pa, u32 win, u32 size, u32 align)
+uintptr
+upaallocwin(uintptr pa, u32 win, u32 size, u32 align)
 {
 	uvlong a, base, top = pa + win;
 
@@ -305,7 +316,7 @@
 }
 
 void
-upafree(u64 pa, u32 size)
+upafree(uintptr pa, u32 size)
 {
 	memmapfree(pa, size, MemUPA);
 }
--- a/os/pc64/mmu.c
+++ b/os/pc64/mmu.c
@@ -5,6 +5,30 @@
 #include	"fns.h"
 #include	"io.h"
 
+/*
+mmu.c: differs between pc and pc64
+	- on 9front:
+	pmap() - setup up page table entries for the physical address in virtual memory
+			the virtual memory address is a parameter
+			the flags are included in the physical address
+			used by memory.c:^mapkzero for setting the page tables of the kernel
+	vmap() - setup page tables for device memory
+			virtual memory address = device memory address
+			used by almost all the device drivers accessing registers
+				as memory addresses (unbacked physical address)
+	kmap() - setup kernel page tables
+			virtual memory address = page address + KMAP
+	A process's virtual memory usage is maintained in the PMMU data structure
+		on inferno:
+	1. there is no separate virtual memory address - linear mapping
+	2. As all memory is linear and global, there is no need to maintain
+		a per-process list of page tables
+	3. pmap() without the parameter for the virtual memory address handles the
+		above needs
+	3. vmap() is  a wrapper around pmap() specialized for unbacked physical
+		addresses
+	4. kmap() is obsolete
+ */
 #define DP	if(1){}else print
 /*
  * Simple segment descriptors with no translation.
@@ -137,15 +161,40 @@
 return 0;
 }
 
+/*
+ * Add a device mapping to the vmap range.
+ * note that the VMAP and KZERO PDPs are shared
+ * between processors (see mpstartap) so no
+ * synchronization is being done.
+ *
+ * < cinap_lenrek> joe7: pmap() is kind of generic function,
+ *  allowing to pass the protection flags too
+ * < cinap_lenrek> vmap() and kmap() are all built ontop of it
+ */
 void*
 vmap(uintptr pa, int size)
 {
-return 0;
+        int o;
+
+        if(pa < BY2PG || size <= 0 || -pa < size || pa+size > VMAPSIZE){
+                print("vmap pa=%llux size=%d pc=%#p\n", pa, size, getcallerpc(&pa));
+                return nil;
+        }
+
+        /*
+         * might be asking for less than a page.
+         */
+        o = pa & (BY2PG-1);
+        pa -= o;
+        size += o;
+        pmap(pa, PTEUNCACHED|PTEWRITE|PTENOEXEC|PTEVALID, size);
+        return (void*)(pa+o);
 }
 
 void
 vunmap(void *va, int size)
 {
+/* nothing to do */
 }
 
 long
--- a/os/port/memmap.c
+++ b/os/port/memmap.c
@@ -11,9 +11,9 @@
 typedef struct Mapent Mapent;
 struct Mapent
 {
-	ulong	type;
-	uvlong	addr;
-	uvlong	size;
+	u32	type;
+	uintptr	addr;
+	uintptr	size;
 };
 
 static struct {
@@ -52,12 +52,12 @@
 		default:
 			 strncpy(tstr+n, "unknown type", 64-n);
 	}
-	print("%.16llux-%.16llux %lux	%s\n",
+	print("%.16zux-%.16zux %ux	%s\n",
 		e->addr, e->addr + e->size, e->type, (char*)tstr);
 }
 
 static int
-insert(uvlong addr, uvlong size, ulong type)
+insert(uintptr addr, uintptr size, u32 type)
 {
 	Mapent *e;
 
@@ -76,7 +76,7 @@
 }
 
 static Mapent*
-lookup(uvlong addr)
+lookup(uintptr addr)
 {
 	Mapent *i, *e;
 
@@ -182,7 +182,7 @@
 }
 
 uvlong
-memmapnext(uvlong addr, ulong type)
+memmapnext(uintptr addr, u32 type)
 {
 	Mapent *i, *e;
 
@@ -201,7 +201,7 @@
 }
 
 uvlong
-memmapsize(uvlong addr, uvlong align)
+memmapsize(uintptr addr, uintptr align)
 {
 	Mapent *i;
 	uvlong size;
@@ -222,7 +222,7 @@
 }
 
 void
-memmapadd(uvlong addr, uvlong size, ulong type)
+memmapadd(uintptr addr, uintptr size, u32 type)
 {
 	type &= ~Allocated;
 	lock(&mapalloc);
@@ -234,8 +234,8 @@
 	unlock(&mapalloc);
 }
 
-uvlong
-memmapalloc(uvlong addr, uvlong size, uvlong align, u32 type)
+uintptr
+memmapalloc(uintptr addr, uintptr size, uintptr align, u32 type)
 {
 	Mapent *i, *e;
 
@@ -280,7 +280,7 @@
 }
 
 void
-memmapfree(uvlong addr, uvlong size, ulong type)
+memmapfree(uintptr addr, uintptr size, u32 type)
 {
 	Mapent *i;
 
--- a/os/port/portfns.h
+++ b/os/port/portfns.h
@@ -157,11 +157,11 @@
 void*		mallocz(ulong, int);
 Block*		mem2bl(uchar*, int);
 void		memmapdump(void);
-uvlong		memmapnext(uvlong, ulong);
-uvlong		memmapsize(uvlong, uvlong);
-void		memmapadd(uvlong, uvlong, ulong);
-uvlong		memmapalloc(uvlong, uvlong, uvlong, u32);
-void		memmapfree(uvlong, uvlong, ulong);
+uintptr		memmapnext(uintptr, u32);
+uintptr		memmapsize(uintptr, uintptr);
+void		memmapadd(uintptr, uintptr, u32);
+uintptr		memmapalloc(uintptr, uintptr, uintptr, u32);
+void		memmapfree(uintptr, uintptr, u32);
 int			memusehigh(void);
 void		microdelay(int);
 uvlong		mk64fract(uvlong, uvlong);