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);