81 lines
1.5 KiB
C
81 lines
1.5 KiB
C
/*
|
|
* Copyright (c) 2013-2014 Stanford University
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#include <stdarg.h>
|
|
#include <stdint.h>
|
|
|
|
#include <cdefs.h>
|
|
#include <kassert.h>
|
|
#include <kmem.h>
|
|
#include <queue.h>
|
|
|
|
#include "../amd64/amd64.h"
|
|
|
|
/* 'FREEPAGE' */
|
|
#define FREEPAGE_MAGIC_FREE 0x4652454550414745ULL
|
|
/* 'ALLOCATE' */
|
|
#define FREEPAGE_MAGIC_INUSE 0x414c4c4f43415445ULL
|
|
|
|
typedef struct FreePage
|
|
{
|
|
uint64_t magic;
|
|
LIST_ENTRY(FreePage) entries;
|
|
} FreePage;
|
|
|
|
LIST_HEAD(FreeListHead, FreePage) freeList;
|
|
|
|
void
|
|
PAlloc_Init()
|
|
{
|
|
LIST_INIT(&freeList);
|
|
}
|
|
|
|
void
|
|
PAlloc_AddRegion(uintptr_t start, uintptr_t len)
|
|
{
|
|
uintptr_t i;
|
|
FreePage *pg;
|
|
|
|
if ((start % PGSIZE) != 0)
|
|
Panic("Region start is not page aligned!");
|
|
if ((len % PGSIZE) != 0)
|
|
Panic("Region length is not page aligned!");
|
|
|
|
for (i = 0; i < len; i += PGSIZE)
|
|
{
|
|
pg = (void *)(start + i);
|
|
pg->magic = FREEPAGE_MAGIC_FREE;
|
|
LIST_INSERT_HEAD(&freeList, pg, entries);
|
|
}
|
|
}
|
|
|
|
void *
|
|
PAlloc_AllocPage()
|
|
{
|
|
FreePage *pg = LIST_FIRST(&freeList);
|
|
LIST_REMOVE(pg, entries);
|
|
|
|
ASSERT(pg->magic == FREEPAGE_MAGIC_FREE);
|
|
pg->magic = FREEPAGE_MAGIC_INUSE;
|
|
|
|
//kprintf("PAlloc_AllocPage: %08llx\n", pg);
|
|
return (void *)pg;
|
|
}
|
|
|
|
void
|
|
PAlloc_FreePage(void *region)
|
|
{
|
|
FreePage *pg = (FreePage *)region;
|
|
LIST_INSERT_HEAD(&freeList, pg, entries);
|
|
|
|
#ifndef NDEBUG
|
|
// Application can write this magic, but for
|
|
// debug builds we can use this as a double free check.
|
|
ASSERT(pg->magic != FREEPAGE_MAGIC_FREE);
|
|
#endif
|
|
pg->magic = FREEPAGE_MAGIC_FREE;
|
|
}
|
|
|