diff --git a/armcompile.mk b/armcompile.mk index c3f26a2..593d34d 100644 --- a/armcompile.mk +++ b/armcompile.mk @@ -44,9 +44,9 @@ OBJCOPY := $(ARMDIR)/$(ARMPREFIX)-objcopy # Define the default flags for compilation. DEFS := -D__COMROGUE_INTERNALS__ INCLUDES := -I$(CRBASEDIR)/include -I$(CRBASEDIR)/idl -CFLAGS := $(INCLUDES) -mabi=aapcs -mfloat-abi=hard -mcpu=arm1176jzf-s -Wall -O2 \ +CFLAGS := $(INCLUDES) -mabi=aapcs -mfloat-abi=hard -mcpu=arm1176jzf-s -Wall -Werror -O2 \ -nostdlib -nostartfiles -ffreestanding $(DEFS) -AFLAGS := -mcpu=arm1176jzf-s -mfloat-abi=hard +AFLAGS := -mcpu=arm1176jzf-s -mfloat-abi=hard --fatal-warnings ASM_CPP_FLAGS := $(INCLUDES) $(DEFS) -D__ASM__ # Standard rule for pre-processing linker script files. diff --git a/include/comrogue/internals/memmgr.h b/include/comrogue/internals/memmgr.h index 2f1efa8..11985ee 100644 --- a/include/comrogue/internals/memmgr.h +++ b/include/comrogue/internals/memmgr.h @@ -49,7 +49,8 @@ /* Nodes in the page table tree. */ typedef struct tagPAGENODE { - RBTREENODE rbtn; /* RBT node containing physical address as key */ + RBTREENODE rbtn; /* RBT node */ + PHYSADDR paPageTable; /* physical address of page table */ PPAGETAB ppt; /* pointer to page table */ } PAGENODE, *PPAGENODE; diff --git a/include/comrogue/internals/rbtree.h b/include/comrogue/internals/rbtree.h index 74be24e..5b0457d 100644 --- a/include/comrogue/internals/rbtree.h +++ b/include/comrogue/internals/rbtree.h @@ -57,48 +57,56 @@ typedef INT32 (*PFNTREECOMPARE)(TREEKEY, TREEKEY); /* The basic tree node. */ typedef struct tagRBTREENODE { - struct tagRBTREENODE *ptnLeft; /* pointer to left child */ - UINT_PTR ptnRightColor; /* pointer to right child AND color stored in low-order bit */ - TREEKEY treekey; /* key value */ + struct tagRBTREENODE *ptnLeft; /* pointer to left child */ + UINT_PTR ptnRightColor; /* pointer to right child AND color stored in low-order bit */ } RBTREENODE, *PRBTREENODE; -/* Tree node macros, mostly to access either color or pointer or both from the ptnRightColor field */ +/* Tree node macros, mostly to access either color or pointer or both from the pRightColor field */ #define rbtNodeRight(ptn) ((PRBTREENODE)((ptn)->ptnRightColor & ~1)) #define rbtNodeColor(ptn) ((ptn)->ptnRightColor & 1) #define rbtIsRed(ptn) ((ptn) ? rbtNodeColor(ptn) : FALSE) #define rbtSetNodeRight(ptn, ptnR) \ - do { (ptn)->ptnRightColor = (((UINT_PTR)(ptnR)) & ~1) | ((ptn)->ptnRightColor & 1); } while (0) + do { (ptn)->ptnRightColor = (((UINT_PTR)(ptnR)) & ~1) | ((ptn)->ptnRightColor & 1); } while (0) #define rbtSetNodeColor(ptn, clr) \ do { (ptn)->ptnRightColor = ((ptn)->ptnRightColor & ~1) | ((clr) ? 1 : 0); } while (0) #define rbtToggleColor(ptn) do { if (ptn) (ptn)->ptnRightColor ^= 1; } while (0) -#define rbtInitNode(ptn, ptnL, ptnR, clr, key) \ - do { (ptn)->ptnLeft = (ptnL); (ptn)->ptnRightColor = (((UINT_PTR)(ptnR)) & ~1) | ((clr) ? 1 : 0); \ - (ptn)->treekey = (TREEKEY)(key); } while (0) -#define rbtNewNode(ptn, key) rbtInitNode(ptn, NULL, NULL, RED, key) +#define rbtInitNode(ptn, ptnL, ptnR, clr) \ + do { (ptn)->ptnLeft = (ptnL); (ptn)->ptnRightColor = (((UINT_PTR)(ptnR)) & ~1) | ((clr) ? 1 : 0); } while (0) +#define rbtNewNode(ptn) rbtInitNode(ptn, NULL, NULL, RED) + +/* Accessor functions common to tree instances. */ +typedef TREEKEY (*PFNGETTREEKEY)(PVOID); +typedef PRBTREENODE (*PFNGETTREENODEPTR)(PVOID); +typedef PVOID (*PFNGETFROMTREENODEPTR)(PRBTREENODE); /* The head-of-tree structure. */ typedef struct tagRBTREE { - PFNTREECOMPARE pfnTreeCompare; /* pointer to comparison function */ - PRBTREENODE ptnRoot; /* pointer to root of tree */ + PFNTREECOMPARE pfnTreeCompare; /* pointer to comparison function */ + PFNGETTREEKEY pfnGetTreeKey; /* pointer to key-retrieval function */ + PFNGETTREENODEPTR pfnGetNodePtr; /* pointer to node-pointer retrieval function */ + PFNGETFROMTREENODEPTR pfnGetFromNodePtr; /* pointer to func to get the tree node from node pointer */ + PRBTREENODE ptnRoot; /* pointer to root of tree */ } RBTREE, *PRBTREE; /* Tree macros. */ -#define rbtInitTree(ptree, pfnCompare) \ - do { (ptree)->pfnTreeCompare = (pfnCompare); (ptree)->ptnRoot = NULL; } while (0) +#define rbtInitTree(ptree, pfnCompare, pfnGetKey, pfnToNodePtr, pfnFromNodePtr) \ + do { (ptree)->pfnTreeCompare = (pfnCompare); (ptree)->pfnGetTreeKey = (pfnGetKey); \ + (ptree)->pfnGetNodePtr = (pfnToNodePtr); (ptree)->pfnGetFromNodePtr = (pfnFromNodePtr); \ + (ptree)->ptnRoot = NULL; } while (0) #define rbtIsEmpty(ptree) MAKEBOOL(!((ptree)->ptnRoot)) /* Type of function used by RbtWalk. */ -typedef BOOL (*PFNRBTWALK)(PRBTREE, PRBTREENODE, PVOID); +typedef BOOL (*PFNRBTWALK)(PRBTREE, PVOID, PVOID); /* Function prototypes. */ CDECL_BEGIN extern INT32 RbtStdCompareByValue(TREEKEY k1, TREEKEY k2); -extern void RbtInsert(PRBTREE ptree, PRBTREENODE ptnNew); -extern PRBTREENODE RbtFind(PRBTREE ptree, TREEKEY key); -extern PRBTREENODE RbtFindPredecessor(PRBTREE ptree, TREEKEY key); -extern PRBTREENODE RbtFindSuccessor(PRBTREE ptree, TREEKEY key); -extern PRBTREENODE RbtFindMin(PRBTREE ptree); +extern void RbtInsert(PRBTREE ptree, PVOID ptnNew); +extern PVOID RbtFind(PRBTREE ptree, TREEKEY key); +extern PVOID RbtFindPredecessor(PRBTREE ptree, TREEKEY key); +extern PVOID RbtFindSuccessor(PRBTREE ptree, TREEKEY key); +extern PVOID RbtFindMin(PRBTREE ptree); extern void RbtDelete(PRBTREE ptree, TREEKEY key); extern BOOL RbtWalk(PRBTREE ptree, PFNRBTWALK pfnWalk, PVOID pData); diff --git a/kernel/lib/rbtree.c b/kernel/lib/rbtree.c index f693195..52b7cd8 100644 --- a/kernel/lib/rbtree.c +++ b/kernel/lib/rbtree.c @@ -31,12 +31,6 @@ */ #include #include -#include - -#ifdef THIS_FILE -#undef THIS_FILE -DECLARE_THIS_FILE -#endif /*------------------------------------------------------------------------------------------------------ * An implementation of left-leaning red-black 2-3 trees as detailed in "Left-leaning Red-Black Trees," @@ -155,8 +149,9 @@ static PRBTREENODE fix_up(PRBTREENODE ptn) * - ptree = Pointer to the tree head structure, containing the compare function. * - ptnCurrent = Pointer to the current subtree we're inserting into. * - ptnNew = Pointer to the new tree node to be inserted. This node must have been initialized with - * the rbtInitNode macro to contain a key, NULL left and right pointers, and be red. It is + * the rbtInitNode macro to contain NULL left and right pointers and be red. It is * assumed that the node's key does NOT already exist in the tree. + * - keyNew = Tree key for the new node. * * Returns: * The pointer to the new subtree after the insertion is performed. @@ -165,18 +160,20 @@ static PRBTREENODE fix_up(PRBTREENODE ptn) * This function is recursive; however, the nature of the tree guarantees that the stack space consumed * by its stack frames will be O(log n). */ -static PRBTREENODE insert_under(PRBTREE ptree, PRBTREENODE ptnCurrent, PRBTREENODE ptnNew) +static PRBTREENODE insert_under(PRBTREE ptree, PRBTREENODE ptnCurrent, PRBTREENODE ptnNew, TREEKEY keyNew) { register int cmp; /* compare result */ + register TREEKEY keyCurrent; if (!ptnCurrent) return ptnNew; /* degenerate case */ - cmp = (*(ptree->pfnTreeCompare))(ptnNew->treekey, ptnCurrent->treekey); + keyCurrent = (*(ptree->pfnGetTreeKey))((*(ptree->pfnGetFromNodePtr))(ptnCurrent)); + cmp = (*(ptree->pfnTreeCompare))(keyNew, keyCurrent); //ASSERT(cmp != 0); if (cmp < 0) - ptnCurrent->ptnLeft = insert_under(ptree, ptnCurrent->ptnLeft, ptnNew); + ptnCurrent->ptnLeft = insert_under(ptree, ptnCurrent->ptnLeft, ptnNew, keyNew); else - rbtSetNodeRight(ptnCurrent, insert_under(ptree, rbtNodeRight(ptnCurrent), ptnNew)); + rbtSetNodeRight(ptnCurrent, insert_under(ptree, rbtNodeRight(ptnCurrent), ptnNew, keyNew)); return fix_up(ptnCurrent); } @@ -185,16 +182,17 @@ static PRBTREENODE insert_under(PRBTREE ptree, PRBTREENODE ptnCurrent, PRBTREENO * * Parameters: * - ptree = Pointer to the tree head structure. - * - ptnNew = Pointer to the new tree node to be inserted. This node must have been initialized with - * the rbtInitNode macro to contain a key, NULL left and right pointers, and be red. It is - * assumed that the node's key does NOT already exist in the tree. + * - pNew = Pointer to the new tree node to be inserted. This node must have been initialized with + * the rbtInitNode macro to contain NULL left and right pointers, and be red. It is + * assumed that the node's key does NOT already exist in the tree. * * Returns: * Nothing. */ -void RbtInsert(PRBTREE ptree, PRBTREENODE ptnNew) +void RbtInsert(PRBTREE ptree, PVOID pNew) { - ptree->ptnRoot = insert_under(ptree, ptree->ptnRoot, ptnNew); + ptree->ptnRoot = insert_under(ptree, ptree->ptnRoot, (*(ptree->pfnGetNodePtr))(pNew), + (*(ptree->pfnGetTreeKey))(pNew)); rbtSetNodeColor(ptree->ptnRoot, BLACK); } @@ -208,23 +206,25 @@ void RbtInsert(PRBTREE ptree, PRBTREENODE ptnNew) * Returns: * Pointer to the node where the key is found, or NULL if not found. */ -PRBTREENODE RbtFind(PRBTREE ptree, TREEKEY key) +PVOID RbtFind(PRBTREE ptree, TREEKEY key) { + register PVOID pCurrent; /* pointer to current node */ register PRBTREENODE ptn = ptree->ptnRoot; /* current node */ register int cmp; /* compare result */ while (ptn) { - cmp = (*(ptree->pfnTreeCompare))(key, ptn->treekey); + pCurrent = (*(ptree->pfnGetFromNodePtr))(ptn); + cmp = (*(ptree->pfnTreeCompare))(key, (*(ptree->pfnGetTreeKey))(pCurrent)); if (cmp == 0) - break; /* found */ + return pCurrent; /* found */ else if (cmp < 0) ptn = ptn->ptnLeft; else ptn = rbtNodeRight(ptn); } - return ptn; + return NULL; } /* @@ -239,27 +239,29 @@ PRBTREENODE RbtFind(PRBTREE ptree, TREEKEY key) * Pointer to the node where the key is found, or pointer to the predecessor node, or NULL if the key * is less than every key in the tree and hence has no predecessor. */ -PRBTREENODE RbtFindPredecessor(PRBTREE ptree, TREEKEY key) +PVOID RbtFindPredecessor(PRBTREE ptree, TREEKEY key) { + register PVOID pCurrent; /* pointer to current node */ register PRBTREENODE ptn = ptree->ptnRoot; /* current node */ register int cmp; /* compare result */ while (ptn) { - cmp = (*(ptree->pfnTreeCompare))(key, ptn->treekey); + pCurrent = (*(ptree->pfnGetFromNodePtr))(ptn); + cmp = (*(ptree->pfnTreeCompare))(key, (*(ptree->pfnGetTreeKey))(pCurrent)); if (cmp == 0) - break; /* found */ + return pCurrent; /* found */ else if (cmp > 0) { if (rbtNodeRight(ptn)) ptn = rbtNodeRight(ptn); else - break; /* found predecessor */ + return pCurrent; /* found predecessor */ } else ptn = ptn->ptnLeft; } - return ptn; + return NULL; /* not found */ } /* @@ -274,27 +276,29 @@ PRBTREENODE RbtFindPredecessor(PRBTREE ptree, TREEKEY key) * Pointer to the node where the key is found, or pointer to the successor node, or NULL if the key * is greater than every key in the tree and hence has no successor. */ -PRBTREENODE RbtFindSuccessor(PRBTREE ptree, TREEKEY key) +PVOID RbtFindSuccessor(PRBTREE ptree, TREEKEY key) { + register PVOID pCurrent; /* pointer to current node */ register PRBTREENODE ptn = ptree->ptnRoot; /* current node */ register int cmp; /* compare result */ while (ptn) { - cmp = (*(ptree->pfnTreeCompare))(key, ptn->treekey); + pCurrent = (*(ptree->pfnGetFromNodePtr))(ptn); + cmp = (*(ptree->pfnTreeCompare))(key, (*(ptree->pfnGetTreeKey))(pCurrent)); if (cmp == 0) - break; /* found */ + return pCurrent; /* found */ else if (cmp < 0) { if (ptn->ptnLeft) ptn = ptn->ptnLeft; else - break; /* found successor */ + return pCurrent; /* found successor */ } else ptn = rbtNodeRight(ptn); } - return ptn; + return NULL; /* not found */ } /* @@ -322,9 +326,11 @@ static PRBTREENODE find_min(PRBTREENODE ptn) * Returns: * Pointer to the leftmost node in the tree. If the tree has no nodes, NULL is returned. */ -PRBTREENODE RbtFindMin(PRBTREE ptree) +PVOID RbtFindMin(PRBTREE ptree) { - return ptree->ptnRoot ? find_min(ptree->ptnRoot) : NULL; + if (ptree->ptnRoot) + return (*(ptree->pfnGetFromNodePtr))(find_min(ptree->ptnRoot)); + return NULL; } /* @@ -412,7 +418,8 @@ static PRBTREENODE delete_min(PRBTREENODE ptn) */ static PRBTREENODE delete_from_under(PRBTREE ptree, PRBTREENODE ptnCurrent, TREEKEY key) { - register int cmp = (*(ptree->pfnTreeCompare))(key, ptnCurrent->treekey); + register TREEKEY keyCurrent = (*(ptree->pfnGetTreeKey))((*(ptree->pfnGetFromNodePtr))(ptnCurrent)); + register int cmp = (*(ptree->pfnTreeCompare))(key, keyCurrent); if (cmp < 0) { /* hunt down the left subtree */ @@ -425,7 +432,8 @@ static PRBTREENODE delete_from_under(PRBTREE ptree, PRBTREENODE ptnCurrent, TREE if (rbtIsRed(ptnCurrent->ptnLeft)) { ptnCurrent = rotate_right(ptnCurrent); - cmp = (*(ptree->pfnTreeCompare))(key, ptnCurrent->treekey); + keyCurrent = (*(ptree->pfnGetTreeKey))((*(ptree->pfnGetFromNodePtr))(ptnCurrent)); + cmp = (*(ptree->pfnTreeCompare))(key, keyCurrent); } if ((cmp == 0) && !rbtNodeRight(ptnCurrent)) return ptnCurrent->ptnLeft; /* degenerate case */ @@ -433,7 +441,8 @@ static PRBTREENODE delete_from_under(PRBTREE ptree, PRBTREENODE ptnCurrent, TREE && (!rbtNodeRight(ptnCurrent) || !rbtIsRed(rbtNodeRight(ptnCurrent)->ptnLeft))) { ptnCurrent = move_red_right(ptnCurrent); - cmp = (*(ptree->pfnTreeCompare))(key, ptnCurrent->treekey); + keyCurrent = (*(ptree->pfnGetTreeKey))((*(ptree->pfnGetFromNodePtr))(ptnCurrent)); + cmp = (*(ptree->pfnTreeCompare))(key, keyCurrent); } if (cmp == 0) { @@ -495,7 +504,7 @@ static BOOL do_walk(PRBTREE ptree, PRBTREENODE ptn, PFNRBTWALK pfnWalk, PVOID pD if (ptn->ptnLeft) rc = do_walk(ptree, ptn->ptnLeft, pfnWalk, pData); if (rc) - rc = (*pfnWalk)(ptree, ptn, pData); + rc = (*pfnWalk)(ptree, (*(ptree->pfnGetFromNodePtr))(ptn), pData); if (rc && rbtNodeRight(ptn)) rc = do_walk(ptree, rbtNodeRight(ptn), pfnWalk, pData); return rc; diff --git a/kernel/mm/kernel_space.c b/kernel/mm/kernel_space.c index 02fc521..dd47ca0 100644 --- a/kernel/mm/kernel_space.c +++ b/kernel/mm/kernel_space.c @@ -176,6 +176,48 @@ typedef struct tagALLOC_STRUC { static RBTREE g_rbtFreeAddrs; /* free address tree */ static PMALLOC g_pMalloc = NULL; /* allocator we use */ +/* + * Given a pointer to an ADDRTREENODE, returns its key value (pointer to its interval). + * + * Parameters: + * - patn = Pointer to the ADDRTREENODE. + * + * Returns: + * Pointer to its embedded address interval. + */ +static TREEKEY get_interval_from_addrtreenode(PVOID patn) +{ + return (TREEKEY)(&(((PADDRTREENODE)patn)->ai)); +} + +/* + * Given a pointer to an ADDRTREENODE, returns a pointer to its embedded RBTREENODE. + * + * Parameters: + * - patn = Pointer to the ADDRTREENODE. + * + * Returns: + * Pointer to the embedded RBTREENODE. + */ +static PRBTREENODE get_rbtreenode_from_addrtreenode(PVOID patn) +{ + return &(((PADDRTREENODE)patn)->rbtn); +} + +/* + * Given a pointer to a RBTREENODE, returns a pointer to the ADDRTREENODE containing it. + * + * Parameters: + * - ptn = Pointer to the RBTREENODE. + * + * Returns: + * Pointer to the containing ADDRTREENODE. + */ +static PVOID get_addrtreenode_from_rbtreenode(PRBTREENODE ptn) +{ + return (PVOID)(((PCHAR)ptn) - OFFSETOF(ADDRTREENODE, rbtn)); +} + /* * Inserts a kernel address range into the tree. * @@ -193,8 +235,9 @@ static void insert_into_tree(KERNADDR kaFirst, KERNADDR kaLast) { PADDRTREENODE pnode = IMalloc_Alloc(g_pMalloc, sizeof(ADDRTREENODE)); ASSERT(pnode); - rbtNewNode(&(pnode->rbtn), init_interval(&(pnode->ai), kaFirst, kaLast)); - RbtInsert(&g_rbtFreeAddrs, (PRBTREENODE)pnode); + rbtNewNode(&(pnode->rbtn)); + init_interval(&(pnode->ai), kaFirst, kaLast); + RbtInsert(&g_rbtFreeAddrs, pnode); } /* @@ -288,8 +331,8 @@ void _MmFreeKernelAddr(KERNADDR kaBase, UINT32 cpgToFree) init_interval_pages(&aiFree, kaBase, cpgToFree); ASSERT(!RbtFind(&g_rbtFreeAddrs, (TREEKEY)(&aiFree))); - patnPred = (PADDRTREENODE)RbtFindPredecessor(&g_rbtFreeAddrs, (TREEKEY)(&aiFree)); - patnSucc = (PADDRTREENODE)RbtFindSuccessor(&g_rbtFreeAddrs, (TREEKEY)(&aiFree)); + patnPred = (PADDRTREENODE)RbtFindPredecessor(&g_rbtFreeAddrs, (&aiFree)); + patnSucc = (PADDRTREENODE)RbtFindSuccessor(&g_rbtFreeAddrs, (&aiFree)); if (patnPred && intervals_adjacent(&(patnPred->ai), &aiFree)) { if (patnSucc && intervals_adjacent(&aiFree, &(patnSucc->ai))) @@ -321,7 +364,8 @@ SEG_INIT_CODE void _MmInitKernelSpace(PSTARTUP_INFO pstartup, PMALLOC pmInitHeap { g_pMalloc = pmInitHeap; IUnknown_AddRef(g_pMalloc); - rbtInitTree(&g_rbtFreeAddrs, (PFNTREECOMPARE)interval_compare); + rbtInitTree(&g_rbtFreeAddrs, (PFNTREECOMPARE)interval_compare, get_interval_from_addrtreenode, + get_rbtreenode_from_addrtreenode, get_addrtreenode_from_rbtreenode); insert_into_tree(pstartup->vmaFirstFree, VMADDR_IO_BASE); insert_into_tree(VMADDR_IO_BASE + (PAGE_COUNT_IO * SYS_PAGE_SIZE), VMADDR_KERNEL_NOMANS); } diff --git a/kernel/mm/vmmap.c b/kernel/mm/vmmap.c index af0884a..2558ba5 100644 --- a/kernel/mm/vmmap.c +++ b/kernel/mm/vmmap.c @@ -62,6 +62,53 @@ static VMCTXT g_vmctxtKernel = { /* kernel VM context */ static RBTREE g_rbtFreePageTables; /* tree containing free page tables */ static PFNSETPTEADDR g_pfnSetPTEAddr = NULL; /* hook function into page database */ +/*----------------------------------- + * Red-black tree accessor functions + *----------------------------------- + */ + +/* + * Given a pointer to a PAGENODE, returns its key (the physical address of the page table). + * + * Parameters: + * - ppgn = Pointer to a PAGENODE. + * + * Returns: + * The PAGENODE's key value (the physical address of the page table). + */ +static TREEKEY get_key_from_pagenode(PVOID ppgn) +{ + return (TREEKEY)(((PPAGENODE)ppgn)->paPageTable); +} + +/* + * Given a pointer to a PAGENODE, returns a pointer to the RBTREENODE contained within it. + * + * Parameters: + * - ppgn = Pointer to a PAGENODE. + * + * Returns: + * The PAGENODE's embedded RBTREENODE. + */ +static PRBTREENODE get_rbtreenode_from_pagenode(PVOID ppgn) +{ + return &(((PPAGENODE)ppgn)->rbtn); +} + +/* + * Given a pointer to a RBTREENODE, returns a pointer to the PAGENODE it's embedded in. + * + * Parameters: + * - ptn = Pointer to an RBTREENODE. + * + * Returns: + * The pointer to the PAGENODE the RBTREENODE is embedded in. + */ +static PVOID get_pagenode_from_rbtreenode(PRBTREENODE ptn) +{ + return (PVOID)(((PCHAR)ptn) - OFFSETOF(PAGENODE, rbtn)); +} + /*------------------------------ * Inline resolution operations *------------------------------ @@ -194,8 +241,8 @@ static void free_page_table(PVMCTXT pvmctxt, PPAGETAB ppgt) if (ppgn) { RbtDelete(&(pvmctxt->rbtPageTables), (TREEKEY)pa); - rbtNewNode(&(ppgn->rbtn), ppgn->rbtn.treekey); - RbtInsert(&g_rbtFreePageTables, (PRBTREENODE)ppgn); + rbtNewNode(&(ppgn->rbtn)); + RbtInsert(&g_rbtFreePageTables, ppgn); } } @@ -681,12 +728,14 @@ static HRESULT alloc_page_table(PVMCTXT pvmctxt, PTTB pttbEntry, PTTBAUX pttbAux ppgn = IMalloc_Alloc(g_pMalloc, sizeof(PAGENODE)); if (ppgnFree && ppgn) { /* prepare the new nodes and insert them in their respective trees */ - rbtNewNode(&(ppgnFree->rbtn), paNewPage + sizeof(PAGETAB)); + rbtNewNode(&(ppgnFree->rbtn)); + ppgnFree->paPageTable = paNewPage + sizeof(PAGETAB); ppgnFree->ppt = ((PPAGETAB)kaNewPage) + 1; - RbtInsert(&g_rbtFreePageTables, (PRBTREENODE)ppgnFree); - rbtNewNode(&(ppgn->rbtn), paNewPage); + RbtInsert(&g_rbtFreePageTables, ppgnFree); + rbtNewNode(&(ppgn->rbtn)); + ppgn->paPageTable = paNewPage; ppgn->ppt = (PPAGETAB)kaNewPage; - RbtInsert(&(pvmctxt->rbtPageTables), (PRBTREENODE)ppgn); + RbtInsert(&(pvmctxt->rbtPageTables), ppgn); } else { /* could not allocate both, free one if was allocated */ @@ -712,15 +761,15 @@ static HRESULT alloc_page_table(PVMCTXT pvmctxt, PTTB pttbEntry, PTTBAUX pttbAux else { /* get the first item out of the free-pages tree and reinsert it into the current VM context */ ppgn = (PPAGENODE)RbtFindMin(&g_rbtFreePageTables); - RbtDelete(&g_rbtFreePageTables, ppgn->rbtn.treekey); - rbtNewNode(&(ppgn->rbtn), ppgn->rbtn.treekey); - RbtInsert(&(pvmctxt->rbtPageTables), (PRBTREENODE)ppgn); + RbtDelete(&g_rbtFreePageTables, (TREEKEY)(ppgn->paPageTable)); + rbtNewNode(&(ppgn->rbtn)); + RbtInsert(&(pvmctxt->rbtPageTables), ppgn); } if (SUCCEEDED(hr)) { /* prepare new page table and insert it into the TTB */ StrSetMem(ppgn->ppt, 0, sizeof(PAGETAB)); - pttbEntry->data = (PHYSADDR)(ppgn->rbtn.treekey) | uiTableFlags; /* poke new entry */ + pttbEntry->data = ppgn->paPageTable | uiTableFlags; /* poke new entry */ pttbAuxEntry->data = TTBAUXFLAGS_PAGETABLE; *pppt = ppgn->ppt; } @@ -1066,8 +1115,10 @@ SEG_INIT_CODE void _MmInitVMMap(PSTARTUP_INFO pstartup, PMALLOC pmInitHeap) g_vmctxtKernel.pTTB = (PTTB)(pstartup->kaTTB); g_vmctxtKernel.pTTBAux = (PTTBAUX)(pstartup->kaTTBAux); g_vmctxtKernel.paTTB = pstartup->paTTB; - rbtInitTree(&(g_vmctxtKernel.rbtPageTables), RbtStdCompareByValue); - rbtInitTree(&g_rbtFreePageTables, RbtStdCompareByValue); + rbtInitTree(&(g_vmctxtKernel.rbtPageTables), RbtStdCompareByValue, get_key_from_pagenode, + get_rbtreenode_from_pagenode, get_pagenode_from_rbtreenode); + rbtInitTree(&g_rbtFreePageTables, RbtStdCompareByValue, get_key_from_pagenode, get_rbtreenode_from_pagenode, + get_pagenode_from_rbtreenode); /* * Load all the page tables we know about. They all get mapped in as part of the kernel context, except if @@ -1084,19 +1135,21 @@ SEG_INIT_CODE void _MmInitVMMap(PSTARTUP_INFO pstartup, PMALLOC pmInitHeap) /* allocate node for first page table on page */ ppgn = IMalloc_Alloc(g_pMalloc, sizeof(PAGENODE)); ASSERT(ppgn); - rbtNewNode(&(ppgn->rbtn), paPageTable); + rbtNewNode(&(ppgn->rbtn)); + ppgn->paPageTable = paPageTable; ppgn->ppt = (PPAGETAB)kaPageTable; - RbtInsert(&(g_vmctxtKernel.rbtPageTables), (PRBTREENODE)ppgn); + RbtInsert(&(g_vmctxtKernel.rbtPageTables), ppgn); /* allocate node for second page table on page */ ppgn = IMalloc_Alloc(g_pMalloc, sizeof(PAGENODE)); ASSERT(ppgn); - rbtNewNode(&(ppgn->rbtn), paPageTable + sizeof(PAGETAB)); + rbtNewNode(&(ppgn->rbtn)); + ppgn->paPageTable = paPageTable + sizeof(PAGETAB); ppgn->ppt = ((PPAGETAB)kaPageTable) + 1; if ((i == (pstartup->cpgPageTables - 1)) && pstartup->ctblFreeOnLastPage) - RbtInsert(&g_rbtFreePageTables, (PRBTREENODE)ppgn); + RbtInsert(&g_rbtFreePageTables, ppgn); else - RbtInsert(&(g_vmctxtKernel.rbtPageTables), (PRBTREENODE)ppgn); + RbtInsert(&(g_vmctxtKernel.rbtPageTables), ppgn); paPageTable += SYS_PAGE_SIZE; /* advance to next page table page */ }