2014-06-30 22:52:35 +00:00
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
|
2014-07-22 06:43:01 +00:00
|
|
|
#include <sys/kconfig.h>
|
|
|
|
#include <sys/kassert.h>
|
2014-12-09 01:44:45 +00:00
|
|
|
#include <sys/kdebug.h>
|
2014-07-22 06:43:01 +00:00
|
|
|
#include <sys/kmem.h>
|
|
|
|
|
|
|
|
#include <machine/amd64.h>
|
|
|
|
#include <machine/amd64op.h>
|
|
|
|
#include <machine/pmap.h>
|
|
|
|
#include <machine/mp.h>
|
2014-06-30 22:52:35 +00:00
|
|
|
|
|
|
|
#define MAX_XMEM_REGIONS 1024
|
|
|
|
|
|
|
|
typedef struct XMem
|
|
|
|
{
|
2014-07-17 00:21:18 +00:00
|
|
|
bool inUse;
|
|
|
|
uintptr_t base;
|
|
|
|
uintptr_t maxLength;
|
|
|
|
uintptr_t length;
|
|
|
|
} XMem;
|
2014-06-30 22:52:35 +00:00
|
|
|
|
|
|
|
XMem regions[MAX_XMEM_REGIONS];
|
|
|
|
|
|
|
|
void
|
|
|
|
XMem_Init()
|
|
|
|
{
|
2014-07-17 00:21:18 +00:00
|
|
|
int r;
|
|
|
|
uintptr_t regionSize = MEM_XMAP_LEN / MAX_XMEM_REGIONS;
|
|
|
|
|
2014-06-30 22:52:35 +00:00
|
|
|
kprintf("Initializing XMEM ... ");
|
|
|
|
|
2014-07-17 00:21:18 +00:00
|
|
|
for (r = 0; r < MAX_XMEM_REGIONS; r++)
|
|
|
|
{
|
|
|
|
regions[r].inUse = false;
|
|
|
|
regions[r].base = MEM_XMAP_BASE + r * regionSize;
|
|
|
|
regions[r].maxLength = regionSize;
|
|
|
|
regions[r].length = 0;
|
|
|
|
}
|
|
|
|
|
2014-06-30 22:52:35 +00:00
|
|
|
kprintf("Done!\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
XMem *
|
|
|
|
XMem_New()
|
|
|
|
{
|
2014-07-17 00:21:18 +00:00
|
|
|
int r;
|
|
|
|
|
|
|
|
for (r = 0; r < MAX_XMEM_REGIONS; r++)
|
|
|
|
{
|
|
|
|
if (!regions[r].inUse) {
|
|
|
|
regions[r].inUse = true;
|
|
|
|
return ®ions[r];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-30 22:52:35 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
XMem_Destroy(XMem *xmem)
|
|
|
|
{
|
2014-07-17 00:21:18 +00:00
|
|
|
uintptr_t off;
|
|
|
|
PageEntry *entry;
|
|
|
|
|
|
|
|
for (off = 0; off < xmem->length; off += PGSIZE) {
|
|
|
|
PMap_SystemLookup(xmem->base + off, &entry, PGSIZE);
|
|
|
|
|
|
|
|
// Compute DM
|
|
|
|
|
|
|
|
// Free Page
|
|
|
|
}
|
|
|
|
|
|
|
|
//PMap_SystemUnmap(virt, pages);
|
2014-06-30 22:52:35 +00:00
|
|
|
}
|
|
|
|
|
2014-07-17 00:21:18 +00:00
|
|
|
uintptr_t
|
2014-06-30 22:52:35 +00:00
|
|
|
XMem_GetBase(XMem *xmem)
|
|
|
|
{
|
|
|
|
return xmem->base;
|
|
|
|
}
|
|
|
|
|
2014-07-17 00:21:18 +00:00
|
|
|
uintptr_t
|
2014-06-30 22:52:35 +00:00
|
|
|
XMem_GetLength(XMem *xmem)
|
|
|
|
{
|
|
|
|
return xmem->length;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2014-07-17 00:21:18 +00:00
|
|
|
XMem_Allocate(XMem *xmem, uintptr_t length)
|
2014-06-30 22:52:35 +00:00
|
|
|
{
|
2014-07-17 00:21:18 +00:00
|
|
|
uint64_t off;
|
2014-06-30 22:52:35 +00:00
|
|
|
|
2014-07-17 00:21:18 +00:00
|
|
|
// We already allocated up to that size
|
|
|
|
if (xmem->length > length)
|
|
|
|
return true;
|
2014-06-30 22:52:35 +00:00
|
|
|
|
2014-07-17 00:21:18 +00:00
|
|
|
// Allocation too long
|
|
|
|
if (length > xmem->maxLength)
|
|
|
|
return false;
|
2014-06-30 22:52:35 +00:00
|
|
|
|
2014-07-17 00:21:18 +00:00
|
|
|
for (off = xmem->length; off < length; off += PGSIZE) {
|
|
|
|
void *pg = PAlloc_AllocPage();
|
|
|
|
if (pg == NULL)
|
|
|
|
return false;
|
|
|
|
|
2014-07-31 00:19:24 +00:00
|
|
|
PMap_SystemMap(DMVA2PA((uint64_t)pg), xmem->base + off, 1, 0);
|
2014-09-06 01:34:51 +00:00
|
|
|
|
|
|
|
xmem->length += PGSIZE;
|
2014-07-17 00:21:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2014-06-30 22:52:35 +00:00
|
|
|
}
|
|
|
|
|
2015-02-16 21:32:14 +00:00
|
|
|
static void
|
2014-12-09 01:44:45 +00:00
|
|
|
Debug_XMemStats(int argc, const char *argv[])
|
|
|
|
{
|
|
|
|
int r;
|
|
|
|
|
|
|
|
kprintf("Region Nr: %16s %16s\n", "Base", "Length");
|
|
|
|
for (r = 0; r < MAX_XMEM_REGIONS; r++)
|
|
|
|
{
|
|
|
|
if (regions[r].inUse) {
|
|
|
|
kprintf("Region %2d: %016llx %016llx\n", r,
|
|
|
|
regions[r].base, regions[r].length);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
REGISTER_DBGCMD(xmemstats, "XMem statistics", Debug_XMemStats);
|
|
|
|
|