1 
2 #include <stdbool.h>
3 #include <stdint.h>
4 
5 #include <sys/kconfig.h>
6 #include <sys/kassert.h>
7 #include <sys/kdebug.h>
8 #include <sys/kmem.h>
9 
10 #include <machine/amd64.h>
11 #include <machine/amd64op.h>
12 #include <machine/pmap.h>
13 #include <machine/mp.h>
14 
15 #define MAX_XMEM_REGIONS 1024
16 
17 typedef struct XMem
18 {
19     bool	inUse;
20     uintptr_t	base;
21     uintptr_t	maxLength;
22     uintptr_t	length;
23 } XMem;
24 
25 XMem regions[MAX_XMEM_REGIONS];
26 
27 void
XMem_Init()28 XMem_Init()
29 {
30     int r;
31     uintptr_t regionSize = MEM_XMAP_LEN / MAX_XMEM_REGIONS;
32 
33     kprintf("Initializing XMEM ... ");
34 
35     for (r = 0; r < MAX_XMEM_REGIONS; r++)
36     {
37 	regions[r].inUse = false;
38 	regions[r].base = MEM_XMAP_BASE + r * regionSize;
39 	regions[r].maxLength = regionSize;
40 	regions[r].length = 0;
41     }
42 
43     kprintf("Done!\n");
44 }
45 
46 XMem *
XMem_New()47 XMem_New()
48 {
49     int r;
50 
51     for (r = 0; r < MAX_XMEM_REGIONS; r++)
52     {
53 	if (!regions[r].inUse) {
54 	    regions[r].inUse = true;
55 	    return &regions[r];
56 	}
57     }
58 
59     return NULL;
60 }
61 
62 void
XMem_Destroy(XMem * xmem)63 XMem_Destroy(XMem *xmem)
64 {
65     uintptr_t off;
66     PageEntry *entry;
67 
68     for (off = 0; off < xmem->length; off += PGSIZE) {
69 	PMap_SystemLookup(xmem->base + off, &entry, PGSIZE);
70 
71 	// Compute DM
72 
73 	// Free Page
74     }
75 
76     //PMap_SystemUnmap(virt, pages);
77 }
78 
79 uintptr_t
XMem_GetBase(XMem * xmem)80 XMem_GetBase(XMem *xmem)
81 {
82     return xmem->base;
83 }
84 
85 uintptr_t
XMem_GetLength(XMem * xmem)86 XMem_GetLength(XMem *xmem)
87 {
88     return xmem->length;
89 }
90 
91 bool
XMem_Allocate(XMem * xmem,uintptr_t length)92 XMem_Allocate(XMem *xmem, uintptr_t length)
93 {
94     uint64_t off;
95 
96     // We already allocated up to that size
97     if (xmem->length > length)
98 	return true;
99 
100     // Allocation too long
101     if (length > xmem->maxLength)
102 	return false;
103 
104     for (off = xmem->length; off < length; off += PGSIZE) {
105 	void *pg = PAlloc_AllocPage();
106 	if (pg == NULL)
107 	    return false;
108 
109 	PMap_SystemMap(DMVA2PA((uint64_t)pg), xmem->base + off, 1, 0);
110 
111 	xmem->length += PGSIZE;
112     }
113 
114     return true;
115 }
116 
117 static void
Debug_XMemStats(int argc,const char * argv[])118 Debug_XMemStats(int argc, const char *argv[])
119 {
120     int r;
121 
122     kprintf("Region Nr: %16s %16s\n", "Base", "Length");
123     for (r = 0; r < MAX_XMEM_REGIONS; r++)
124     {
125 	if (regions[r].inUse) {
126 	    kprintf("Region %2d: %016llx %016llx\n", r,
127 		    regions[r].base, regions[r].length);
128 	}
129     }
130 }
131 
132 REGISTER_DBGCMD(xmemstats, "XMem statistics", Debug_XMemStats);
133 
134