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 ®ions[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