Kernel/x86_64 - Rework to use pmemmap.h (and share code with x86)
authorJohn Hodge <[email protected]>
Thu, 9 Aug 2012 16:15:42 +0000 (00:15 +0800)
committerJohn Hodge <[email protected]>
Thu, 9 Aug 2012 16:15:42 +0000 (00:15 +0800)
- Involved breaking the mboot parsing code out of x86/main.c
  and into a helper file x86/mboot.c This file is used by x86_64
  too.
- Added a common boot module format

KernelLand/Kernel/arch/x86/Makefile
KernelLand/Kernel/arch/x86/main.c
KernelLand/Kernel/arch/x86/mboot.c [new file with mode: 0644]
KernelLand/Kernel/arch/x86_64/Makefile
KernelLand/Kernel/arch/x86_64/include/archinit.h [new file with mode: 0644]
KernelLand/Kernel/arch/x86_64/main.c
KernelLand/Kernel/arch/x86_64/mm_phys.c
KernelLand/Kernel/include/bootmod.h [new file with mode: 0644]
KernelLand/Kernel/include/mboot.h

index c83a5af..c3223d0 100644 (file)
@@ -20,7 +20,7 @@ endif
 ASFLAGS += -D USE_MP=$(USE_MP)
 CPPFLAGS += -DUSE_MP=$(USE_MP)
 
-A_OBJ  = start.ao main.o lib.o desctab.ao errors.o irq.o
+A_OBJ  = start.ao main.o mboot.o lib.o desctab.ao errors.o irq.o
 A_OBJ += mm_phys.o mm_virt.o
 A_OBJ += proc.o proc.ao time.o vm8086.o
 A_OBJ += kpanic.o pci.o
index 8fcbaef..af9007d 100644 (file)
@@ -30,18 +30,12 @@ extern int  Time_Setup(void);
 
 // === GLOBALS ===
 char   *gsBootCmdLine = NULL;
-struct {
-       Uint32  PBase;
-       void    *Base;
-       Uint    Size;
-       char    *ArgString;
-}      *gaArch_BootModules;
+tBootModule    *gaArch_BootModules;
  int   giArch_NumBootModules = 0;
 
 // === CODE ===
 int kmain(Uint MbMagic, void *MbInfoPtr)
 {
-       tMBoot_Module   *mods;
        tMBoot_Info     *mbInfo;
        tPMemMapEnt     pmemmap[MAX_PMEMMAP_ENTS];
         int    nPMemMapEnts;
@@ -58,61 +52,13 @@ int kmain(Uint MbMagic, void *MbInfoPtr)
        case MULTIBOOT_MAGIC: {
                // TODO: Handle when this isn't in the mapped area
                gsBootCmdLine = (char*)(mbInfo->CommandLine + KERNEL_BASE);
-               
-               tMBoot_MMapEnt  *ent = (void*)mbInfo->MMapAddr;
-               tMBoot_MMapEnt  *last = (void*)(mbInfo->MMapAddr + mbInfo->MMapLength);
-               
-               // Build up memory map
-               nPMemMapEnts = 0;
-               while( ent < last && nPMemMapEnts < MAX_PMEMMAP_ENTS )
-               {
-                       tPMemMapEnt     *nent = &pmemmap[nPMemMapEnts];
-                       nent->Start = ent->Base;
-                       nent->Length = ent->Length;
-                       switch(ent->Type)
-                       {
-                       case 1:
-                               nent->Type = PMEMTYPE_FREE;
-                               break;
-                       default:
-                               nent->Type = PMEMTYPE_RESERVED;
-                               break;
-                       }
-                       nent->NUMADomain = 0;
-                       
-                       nPMemMapEnts ++;
-                       ent = (void*)( (tVAddr)ent + ent->Size + 4 );
-               }
-
-               // Ensure it's valid
-               nPMemMapEnts = PMemMap_ValidateMap(pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS);
-               // TODO: Error handling
-
-               // Replace kernel with PMEMTYPE_USED
-               nPMemMapEnts = PMemMap_MarkRangeUsed(
-                       pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS,
-                       KERNEL_LOAD, (tVAddr)&gKernelEnd - KERNEL_LOAD - KERNEL_BASE
-                       );
-
-               // Replace modules with PMEMTYPE_USED
-               nPMemMapEnts = PMemMap_MarkRangeUsed(pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS,
-                       mbInfo->Modules, mbInfo->ModuleCount*sizeof(*mods)
-                       );
-               mods = (void*)mbInfo->Modules;
-               for( int i = 0; i < mbInfo->ModuleCount; i ++ )
-               {
-                       nPMemMapEnts = PMemMap_MarkRangeUsed(
-                               pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS,
-                               mods->Start, mods->End - mods->Start
-                               );
-               }
-               
-               // Debug - Output map
-               PMemMap_DumpBlocks(pmemmap, nPMemMapEnts);
 
                // Adjust Multiboot structure address
                mbInfo = (void*)( (Uint)MbInfoPtr + KERNEL_BASE );
-               
+
+               nPMemMapEnts = Multiboot_LoadMemoryMap(mbInfo, KERNEL_BASE, pmemmap, MAX_PMEMMAP_ENTS,
+                       KERNEL_LOAD, (tVAddr)&gKernelEnd - KERNEL_BASE);
+
                break; }
        
        // Multiboot 2
@@ -145,36 +91,7 @@ int kmain(Uint MbMagic, void *MbInfoPtr)
        VFS_Init();
        
        // Load initial modules
-       mods = (void*)( mbInfo->Modules + KERNEL_BASE );
-       giArch_NumBootModules = mbInfo->ModuleCount;
-       gaArch_BootModules = malloc( giArch_NumBootModules * sizeof(*gaArch_BootModules) );
-       for( int i = 0; i < mbInfo->ModuleCount; i ++ )
-       {
-                int    ofs;
-       
-               Log_Log("Arch", "Multiboot Module at 0x%08x, 0x%08x bytes (String at 0x%08x)",
-                       mods[i].Start, mods[i].End-mods[i].Start, mods[i].String);
-       
-               gaArch_BootModules[i].PBase = mods[i].Start;
-               gaArch_BootModules[i].Size = mods[i].End - mods[i].Start;
-       
-               // Always HW map the module data        
-               ofs = mods[i].Start&0xFFF;
-               gaArch_BootModules[i].Base = (void*)( MM_MapHWPages(mods[i].Start,
-                       (gaArch_BootModules[i].Size+ofs+0xFFF) / 0x1000
-                       ) + ofs );
-               
-               // Only map the string if needed
-               if( (tVAddr)mods[i].String > MAX_ARGSTR_POS )
-               {
-                       // Assumes the string is < 4096 bytes long)
-                       gaArch_BootModules[i].ArgString = (void*)(
-                               MM_MapHWPages(mods[i].String, 2) + (mods[i].String&0xFFF)
-                               );
-               }
-               else
-                       gaArch_BootModules[i].ArgString = (char *)mods[i].String + KERNEL_BASE;
-       }
+       gaArch_BootModules = Multiboot_LoadModules(mbInfo, KERNEL_BASE, &giArch_NumBootModules);
        
        // Pass on to Independent Loader
        Log_Log("Arch", "Starting system");
diff --git a/KernelLand/Kernel/arch/x86/mboot.c b/KernelLand/Kernel/arch/x86/mboot.c
new file mode 100644 (file)
index 0000000..5fe4068
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Acess2 Kernel x86 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * mboot.c
+ * - Multiboot Support
+ */
+#define DEBUG  0
+#include <acess.h>
+#include <mboot.h>
+
+// === CODE ===
+int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *Map, const int MapSize, tPAddr KStart, tPAddr KEnd)
+{
+        int    nPMemMapEnts = 0;
+       tMBoot_MMapEnt  *ent = (void*)((tVAddr)MBInfo->MMapAddr + MapOffset);
+       tMBoot_MMapEnt  *last = (void*)((tVAddr)ent + MBInfo->MMapLength);
+       
+       ENTER("pMBInfo pMapOffset pMap iMapSize PKStart PKEnd",
+               MBInfo, MapOffset, Map, MapSize, KStart, KEnd);
+
+       // Build up memory map
+       nPMemMapEnts = 0;
+       while( ent < last && nPMemMapEnts < MapSize )
+       {
+               tPMemMapEnt     *nent = &Map[nPMemMapEnts];
+               nent->Start = ent->Base;
+               nent->Length = ent->Length;
+               switch(ent->Type)
+               {
+               case 1:
+                       nent->Type = PMEMTYPE_FREE;
+                       break;
+               default:
+                       nent->Type = PMEMTYPE_RESERVED;
+                       break;
+               }
+               nent->NUMADomain = 0;
+               
+               nPMemMapEnts ++;
+               ent = (void*)( (tVAddr)ent + ent->Size + 4 );
+       }
+
+       // Ensure it's valid
+       nPMemMapEnts = PMemMap_ValidateMap(Map, nPMemMapEnts, MapSize);
+       // TODO: Error handling
+
+       // Replace kernel with PMEMTYPE_USED
+       nPMemMapEnts = PMemMap_MarkRangeUsed(
+               Map, nPMemMapEnts, MapSize,
+               KStart, KEnd - KStart
+               );
+
+       // Replace modules with PMEMTYPE_USED
+       nPMemMapEnts = PMemMap_MarkRangeUsed(Map, nPMemMapEnts, MapSize,
+               MBInfo->Modules, MBInfo->ModuleCount*sizeof(tMBoot_Module)
+               );
+       tMBoot_Module *mods = (void*)( (tVAddr)MBInfo->Modules + MapOffset);
+       for( int i = 0; i < MBInfo->ModuleCount; i ++ )
+       {
+               nPMemMapEnts = PMemMap_MarkRangeUsed(
+                       Map, nPMemMapEnts, MapSize,
+                       mods->Start, mods->End - mods->Start
+                       );
+       }
+       
+       // Debug - Output map
+       PMemMap_DumpBlocks(Map, nPMemMapEnts);
+
+       LEAVE('i', nPMemMapEnts);
+       return nPMemMapEnts;
+}
+
+tBootModule *Multiboot_LoadModules(tMBoot_Info *MBInfo, tVAddr MapOffset, int *ModuleCount)
+{
+       tMBoot_Module   *mods = (void*)( MBInfo->Modules + MapOffset );
+       *ModuleCount = MBInfo->ModuleCount;
+       tBootModule *ret = malloc( MBInfo->ModuleCount * sizeof(*ret) );
+       for( int i = 0; i < MBInfo->ModuleCount; i ++ )
+       {
+                int    ofs;
+       
+               Log_Log("Arch", "Multiboot Module at 0x%08x, 0x%08x bytes (String at 0x%08x)",
+                       mods[i].Start, mods[i].End-mods[i].Start, mods[i].String);
+       
+               ret[i].PBase = mods[i].Start;
+               ret[i].Size = mods[i].End - mods[i].Start;
+       
+               // Always HW map the module data        
+               ofs = mods[i].Start&0xFFF;
+               ret[i].Base = (void*)( MM_MapHWPages(mods[i].Start,
+                       (ret[i].Size+ofs+0xFFF) / 0x1000
+                       ) + ofs );
+               
+               // Only map the string if needed
+               if( !MM_GetPhysAddr( (void*)(mods[i].String + MapOffset) ) )
+               {
+                       // Assumes the string is < 4096 bytes long)
+                       ret[i].ArgString = (void*)(
+                               MM_MapHWPages(mods[i].String, 2) + (mods[i].String&0xFFF)
+                               );
+               }
+               else
+                       ret[i].ArgString = (char*)(tVAddr)mods[i].String + MapOffset;
+       }
+
+       return ret;
+}
+
index a72216a..4c030a5 100644 (file)
@@ -27,6 +27,7 @@ A_OBJ := start32.ao start64.ao desctab.ao proc.ao
 A_OBJ += main.o lib.o proc.o mm_virt.o mm_phys.o
 A_OBJ += kernelpanic.o errors.o time.o pci.o
 A_OBJ += vm8086.o
+A_OBJ += ../x86/mboot.o
 # rme.o
 
 POSTBUILD = objcopy $(BIN) -F elf32-i386 $(BIN)
diff --git a/KernelLand/Kernel/arch/x86_64/include/archinit.h b/KernelLand/Kernel/arch/x86_64/include/archinit.h
new file mode 100644 (file)
index 0000000..68988b8
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Acess2 Kernel x86_64
+ * - By John Hodge (thePowersGang)
+ *
+ * include/init.h
+ * - Arch-internal init functions
+ */
+#ifndef _ARCH__INIT_H_
+#define _ARCH__INIT_H_
+
+#include <pmemmap.h>
+
+extern void    MM_InitPhys(int NPMemRanges, tPMemMapEnt *PMemRanges);
+
+#endif
+
index cefeeb4..0348de6 100644 (file)
@@ -1,11 +1,18 @@
 /*
- * Acess2 x86_64 Project
+ * Acess2 Kernel x86_64
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Kernel C entrypoint
  */
 #include <acess.h>
 #include <mboot.h>
 #include <init.h>
+#include <archinit.h>
+#include <pmemmap.h>
 
 // === CONSTANTS ===
+#define KERNEL_LOAD    0x100000
 #define MAX_PMEMMAP_ENTS       16
 
 // === IMPORTS ===
@@ -14,7 +21,7 @@ extern void   MM_InitVirt(void);
 extern void    Heap_Install(void);
 extern int     Time_Setup(void);
 
-extern void    MM_InitPhys_Multiboot(tMBoot_Info *MBoot);
+extern char    gKernelEnd[];
 
 // === PROTOTYPES ===
 void   kmain(Uint MbMagic, void *MbInfoPtr);
@@ -26,6 +33,8 @@ char  *gsBootCmdLine = NULL;
 void kmain(Uint MbMagic, void *MbInfoPtr)
 {
        tMBoot_Info     *mbInfo;
+       tPMemMapEnt     pmemmap[MAX_PMEMMAP_ENTS];
+        int    nPMemMapEnts;
 
        LogF("%s\r\n", gsBuildInfo);
        
@@ -41,7 +50,9 @@ void kmain(Uint MbMagic, void *MbInfoPtr)
                // Adjust Multiboot structure address
                mbInfo = (void*)( (Uint)MbInfoPtr + KERNEL_BASE );
                gsBootCmdLine = (char*)( (Uint)mbInfo->CommandLine + KERNEL_BASE);
-               MM_InitPhys_Multiboot( mbInfo );        // Set up physical memory manager
+               nPMemMapEnts = Multiboot_LoadMemoryMap(mbInfo, KERNEL_BASE, pmemmap, MAX_PMEMMAP_ENTS,
+                       KERNEL_LOAD, (tVAddr)&gKernelEnd - KERNEL_BASE
+                       );
                break;
        default:
                Panic("Multiboot magic invalid %08x, expected %08x\n",
@@ -49,6 +60,7 @@ void kmain(Uint MbMagic, void *MbInfoPtr)
                return ;
        }
        
+       MM_InitPhys( nPMemMapEnts, pmemmap );   // Set up physical memory manager
        Log("gsBootCmdLine = '%s'", gsBootCmdLine);
        
        *(Uint16*)(KERNEL_BASE|0xB8000) = 0x1F00|'D';
index b537a9f..27c4946 100644 (file)
@@ -5,7 +5,8 @@
  */
 #define DEBUG  0
 #include <acess.h>
-#include <mboot.h>
+#include <archinit.h>
+#include <pmemmap.h>
 #include <mm_virt.h>
 
 #define TRACE_REF      0
@@ -25,7 +26,7 @@ extern char   gKernelBase[];
 extern char    gKernelEnd[];
 
 // === PROTOTYPES ===
-void   MM_InitPhys_Multiboot(tMBoot_Info *MBoot);
+//void MM_InitPhys(int NPMemRanges, tPMemMapEnt *PMemRanges);
 //tPAddr       MM_AllocPhysRange(int Num, int Bits);
 //tPAddr       MM_AllocPhys(void);
 //void MM_RefPhys(tPAddr PAddr);
@@ -52,6 +53,7 @@ Uint64        giPhysRangeFree[NUM_MM_PHYS_RANGES];    // Number of free pages in each rang
 Uint64 giPhysRangeFirst[NUM_MM_PHYS_RANGES];   // First free page in each range
 Uint64 giPhysRangeLast[NUM_MM_PHYS_RANGES];    // Last free page in each range
 Uint64 giMaxPhysPage = 0;      // Maximum Physical page
+Uint64 giTotalMemorySize = 0;
 // Only used in init, allows the init code to provide pages for use by
 // the allocator before the bitmaps exist.
 // 3 entries because the are three calls to MM_AllocPhys in MM_Map
@@ -62,10 +64,8 @@ tPAddr       gaiStaticAllocPages[NUM_STATIC_ALLOC] = {0};
 /**
  * \brief Initialise the physical memory map using a Multiboot 1 map
  */
-void MM_InitPhys_Multiboot(tMBoot_Info *MBoot)
+void MM_InitPhys(int NPMemRanges, tPMemMapEnt *PMemRanges)
 {
-       tMBoot_MMapEnt  *mmapStart;
-       tMBoot_MMapEnt  *ent;
        Uint64  maxAddr = 0;
         int    numPages, superPages;
         int    i;
@@ -73,226 +73,165 @@ void MM_InitPhys_Multiboot(tMBoot_Info *MBoot)
        tVAddr  vaddr;
        tPAddr  paddr, firstFreePage;
        
-       ENTER("pMBoot=%p", MBoot);
+       ENTER("iNPMemRanges pPMemRanges",
+               NPMemRanges, PMemRanges);
        
        // Scan the physical memory map
        // Looking for the top of physical memory
-       mmapStart = (void *)( KERNEL_BASE | MBoot->MMapAddr );
-       LOG("mmapStart = %p", mmapStart);
-       ent = mmapStart;
-       while( (Uint)ent < (Uint)mmapStart + MBoot->MMapLength )
+       for( i = 0; i < NPMemRanges; i ++ )
        {
+               tPMemMapEnt     *ent = &PMemRanges[i];
                // Adjust for the size of the entry
-               ent->Size += 4;
-               LOG("ent={Type:%i,Base:0x%x,Length:%x",
-                       ent->Type, ent->Base, ent->Length);
+               LOG("%i: ent={Type:%i,Base:0x%x,Length:%x}", i, ent->Type, ent->Start, ent->Length);
                
                // If entry is RAM and is above `maxAddr`, change `maxAddr`
-               if(ent->Type == 1 && ent->Base + ent->Length > maxAddr)
-                       maxAddr = ent->Base + ent->Length;
-               
-               // Go to next entry
-               ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size );
+               if(ent->Type == PMEMTYPE_FREE || ent->Type == PMEMTYPE_USED )
+               {
+                       if( ent->Start + ent->Length > maxAddr)
+                               maxAddr = ent->Start + ent->Length;
+                       giTotalMemorySize += ent->Length >> 12;
+               }
        }
        
-       // Did we find a valid end?
-       if(maxAddr == 0) {
-               // No, darn, let's just use the HighMem hack
-               giMaxPhysPage = (MBoot->HighMem >> 2) + 256;    // HighMem is a kByte value
-       }
-       else {
-               // Goodie, goodie gumdrops
-               giMaxPhysPage = maxAddr >> 12;
-       }
+       giMaxPhysPage = maxAddr >> 12;
        LOG("giMaxPhysPage = 0x%x", giMaxPhysPage);
-       
-       // Find a contigous section of memory to hold it in
-       // - Starting from the end of the kernel
-       // - We also need a region for the super bitmap
+
+       // Get counts of pages needed for basic structures
        superPages = ((giMaxPhysPage+64*8-1)/(64*8) + 0xFFF) >> 12;
-       numPages = (giMaxPhysPage + 7) / 8;
-       numPages = (numPages + 0xFFF) >> 12;
+       numPages = ((giMaxPhysPage+7)/8 + 0xFFF) >> 12; // bytes to hold bitmap, divided up to nearest page
        LOG("numPages = %i, superPages = %i", numPages, superPages);
-       if(maxAddr == 0)
+       
+       // --- Allocate Bitmaps ---
+        int    todo = numPages*2 + superPages;
+        int    mapent = NPMemRanges-1;
+       vaddr = MM_PAGE_BITMAP;
+       paddr = -1;
+       while( todo )
        {
-                int    todo = numPages*2 + superPages;
-               // Ok, naieve allocation, just put it after the kernel
-               // - Allocated Bitmap
-               vaddr = MM_PAGE_BITMAP;
-               paddr = (tPAddr)&gKernelEnd - KERNEL_BASE;
-               while(todo )
+               while(PMemRanges[mapent].Type != PMEMTYPE_FREE && mapent != -1)
+                       mapent --;
+               if( paddr + 1 == 0 )
+                       paddr = PMemRanges[mapent].Start;
+               if( mapent == -1 ) {
+                       // OOM During init, bad thing
+                       Log_KernelPanic("PMem", "Out of memory during init");
+                       for(;;);
+               }
+               
+               // Ensure that the static allocation pool has pages
+               for( i = 0; i < NUM_STATIC_ALLOC; i++)
                {
-                       // Allocate statics
-                       for( i = 0; i < NUM_STATIC_ALLOC; i++) {
-                               if(gaiStaticAllocPages[i] != 0) continue;
+                       if(gaiStaticAllocPages[i] == 0)
+                       {
                                gaiStaticAllocPages[i] = paddr;
-                               paddr += 0x1000;
+                               // break to ensure we update the address correctly
+                               break;
                        }
-                       
+               }
+               
+               if( i == NUM_STATIC_ALLOC )
+               {
+                       // Map
                        MM_Map(vaddr, paddr);
-                       vaddr += 0x1000;
-                       paddr += 0x1000;
-                       
                        todo --;
                        
+                       // Update virtual pointer
+                       vaddr += 0x1000;
                        if( todo == numPages + superPages )
                                vaddr = MM_PAGE_DBLBMP;
                        if( todo == superPages )
                                vaddr = MM_PAGE_SUPBMP;
+               }               
+
+               // Update physical pointer
+               // (underflows are detected at the top of the loop)
+               paddr += 0x1000;
+               if( paddr - PMemRanges[mapent].Start > PMemRanges[mapent].Length )
+                       mapent --;
+               else {
+                       // NOTE: This hides some actually valid memory, but since the pmm
+                       // structures have an "infinite" lifetime, this is of no concequence.
+                       PMemRanges[mapent].Start += 0x1000;
+                       PMemRanges[mapent].Length -= 0x1000;
                }
        }
-       // Scan for a nice range
-       else
-       {
-                int    todo = numPages*2 + superPages;
-               paddr = 0;
-               vaddr = MM_PAGE_BITMAP;
-               // Scan!
-               for(
-                       ent = mmapStart;
-                       (Uint)ent < (Uint)mmapStart + MBoot->MMapLength;
-                       ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size )
-                       )
-               {
-                        int    avail;
-                       
-                       // RAM only please
-                       if( ent->Type != 1 )
-                               continue;
-                       
-                       // Let's not put it below the kernel, shall we?
-                       if( ent->Base + ent->Size < (tPAddr)&gKernelBase )
-                               continue;
-                       
-                       LOG("%x <= %x && %x > %x",
-                               ent->Base, (tPAddr)&gKernelBase,
-                               ent->Base + ent->Size, (tPAddr)&gKernelEnd - KERNEL_BASE
-                               );
-                       // Check if the kernel is in this range
-                       if( ent->Base <= (tPAddr)&gKernelBase
-                       && ent->Base + ent->Length > (tPAddr)&gKernelEnd - KERNEL_BASE )
-                       {
-                               avail = ent->Length >> 12;
-                               avail -= ((tPAddr)&gKernelEnd - KERNEL_BASE - ent->Base) >> 12;
-                               paddr = (tPAddr)&gKernelEnd - KERNEL_BASE;
-                       }
-                       // No? then we can use all of the block
-                       else
-                       {
-                               avail = ent->Length >> 12;
-                               paddr = ent->Base;
-                       }
-                       
-                       Log("MM_InitPhys_Multiboot: paddr=0x%x, avail=0x%x pg", paddr, avail);
-                       
-                       // Map
-                       while( todo && avail --)
-                       {
-                               // Static Allocations
-                               for( i = 0; i < NUM_STATIC_ALLOC && avail; i++) {
-                                       if(gaiStaticAllocPages[i] != 0) continue;
-                                       gaiStaticAllocPages[i] = paddr;
-                                       paddr += 0x1000;
-                                       avail --;
-                               }
-                               if(!avail)      break;
-                               
-                               // Map
-                               MM_Map(vaddr, paddr);
-                               todo --;
-                               vaddr += 0x1000;
-                               paddr += 0x1000;
-                               
-                               // Alter the destination address when needed
-                               if(todo == superPages+numPages)
-                                       vaddr = MM_PAGE_DBLBMP;
-                               if(todo == superPages)
-                                       vaddr = MM_PAGE_SUPBMP;
-                       }
-                       
-                       // Fast quit if there's nothing left to allocate
-                       if( !todo )             break;
-               }
-       }
+
+       PMemMap_DumpBlocks(PMemRanges, NPMemRanges);
+
        // Save the current value of paddr to simplify the allocation later
        firstFreePage = paddr;
        
        LOG("Clearing multi bitmap");
-       // Fill the bitmaps
-       memset(gaMultiBitmap, 0, (numPages<<12)/8);
-       // - initialise to one, then clear the avaliable areas
-       memset(gaMainBitmap, -1, (numPages<<12)/8);
-       memset(gaSuperBitmap, -1, (numPages<<12)/(8*64));
-       LOG("Setting main bitmap");
+       // Fill the bitmaps (set most to "allocated")
+       memset(gaMultiBitmap, 0, numPages<<12);
+       memset(gaMainBitmap,  255, numPages<<12);
        // - Clear all Type=1 areas
        LOG("Clearing valid regions");
-       for(
-               ent = mmapStart;
-               (Uint)ent < (Uint)mmapStart + MBoot->MMapLength;
-               ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size )
-               )
+       for( i = 0; i < NPMemRanges; i ++ )
        {
+               tPMemMapEnt *ent = &PMemRanges[i];
                // Check if the type is RAM
-               if(ent->Type != 1)      continue;
+               if(ent->Type != PMEMTYPE_FREE)  continue;
                
                // Main bitmap
-               base = ent->Base >> 12;
-               size = ent->Size >> 12;
-               
-               if(base & 63) {
-                       Uint64  val = -1LL << (base & 63);
-                       gaMainBitmap[base / 64] &= ~val;
-                       size -= (base & 63);
-                       base += 64 - (base & 63);
-               }
-               memset( &gaMainBitmap[base / 64], 0, size/8 );
-               if( size & 7 ) {
-                       Uint64  val = -1LL << (size & 7);
-                       val <<= (size/8)&7;
-                       gaMainBitmap[base / 64] &= ~val;
+               base = ent->Start >> 12;
+               size = ent->Length >> 12;
+
+               LOG("%i: base=%x, size=%x", i, base, size);
+               if( base % 64 + size < 64 )
+               {
+                       Uint64  bits = (1ULL << size) - 1;
+                       bits <<= base % 64;
+                       gaMainBitmap[base / 64] &= ~bits;
                }
-               
-               // Super Bitmap
-               base = ent->Base >> 12;
-               size = ent->Size >> 12;
-               size = (size + (base & 63) + 63) >> 6;
-               base = base >> 6;
-               if(base & 63) {
-                       Uint64  val = -1LL << (base & 63);
-                       gaSuperBitmap[base / 64] &= ~val;
-//                     size -= (base & 63);
-//                     base += 64 - (base & 63);
+               else
+               {
+                       if(base & 63)
+                       {
+                               // Keep lower bits
+                               Uint64  bits = (1ULL << (base & 63)) - 1;
+                               gaMainBitmap[base / 64] &= bits;
+                               
+                               size -= 64 - base % 64;
+                               base += 64 - base % 64;
+                       }
+                       LOG("%i: base=%x, size=%x", i, base, size);
+                       memset( &gaMainBitmap[base / 64], 0, (size/64)*8 );
+                       base += size & ~(64-1);
+                       size -= size & ~(64-1);
+                       LOG("%i: base=%x, size=%x", i, base, size);
+                       if( size & 63 )
+                       {
+                               // Unset lower bits (hence the bitwise not)
+                               Uint64  val = (1ULL << (size & 63)) - 1;
+                               gaMainBitmap[base / 64] &= ~val;
+                       }
                }
        }
        
-       // Reference the used pages
-       base = (tPAddr)&gKernelBase >> 12;
-       size = firstFreePage >> 12;
-       memset( &gaMainBitmap[base / 64], -1, size/8 );
-       if( size & 7 ) {
-               Uint64  val = -1LL << (size & 7);
-               val <<= (size/8)&7;
-               gaMainBitmap[base / 64] |= val;
-       }
-       
        // Free the unused static allocs
-       for( i = 0; i < NUM_STATIC_ALLOC; i++) {
-               if(gaiStaticAllocPages[i] != 0)
-                       continue;
-               gaMainBitmap[ gaiStaticAllocPages[i] >> (12+6) ]
-                       &= ~(1LL << ((gaiStaticAllocPages[i]>>12)&63));
+       LOG("Freeing unused static allocations");
+       for( i = 0; i < NUM_STATIC_ALLOC; i++)
+       {
+               if(gaiStaticAllocPages[i] == 0)
+               {
+                       gaMainBitmap[ gaiStaticAllocPages[i] >> (12+6) ]
+                               &= ~(1LL << ((gaiStaticAllocPages[i]>>12)&63));
+                       gaiStaticAllocPages[i] = 0;
+               }
        }
        
        // Fill the super bitmap
        LOG("Filling super bitmap");
        memset(gaSuperBitmap, 0, superPages<<12);
-       for( base = 0; base < (size+63)/64; base ++)
+       int nsuperbits = giMaxPhysPage / 64;    // 64 pages per bit
+       for( i = 0; i < (nsuperbits+63)/64; i ++)
        {
-               if( gaMainBitmap[ base ] + 1 == 0 )
-                       gaSuperBitmap[ base/64 ] |= 1LL << (base&63);
+               if( gaMainBitmap[ i ] + 1 == 0 )
+                       gaSuperBitmap[ i/64 ] |= 1ULL << (i % 64);
        }
        
-       // Set free page counts
+       // Set free page counts for each address class
        for( base = 1; base < giMaxPhysPage; base ++ )
        {
                 int    rangeID;
@@ -311,8 +250,8 @@ void MM_InitPhys_Multiboot(tMBoot_Info *MBoot)
                // Set last (when the last free page is reached, this won't be
                // updated anymore, hence will be correct)
                giPhysRangeLast[ rangeID ] = base;
-       }
-       
+       }       
+
        LEAVE('-');
 }
 
diff --git a/KernelLand/Kernel/include/bootmod.h b/KernelLand/Kernel/include/bootmod.h
new file mode 100644 (file)
index 0000000..0979389
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ * 
+ * include/bootmod.h
+ * - Common boot modules type
+ */
+#ifndef _BOOTMOD_H_
+#define _BOOTMOD_H_
+
+typedef struct sBootModule     tBootModule;
+
+struct sBootModule {
+       tPAddr  PBase;
+       void    *Base;
+       Uint    Size;
+       char    *ArgString;
+};
+
+#endif
+
index c7f33dd..61c689b 100644 (file)
@@ -4,9 +4,13 @@
  */
 #ifndef _MBOOT_H
 #define _MBOOT_H
+#include <acess.h>
 
 #define MULTIBOOT_MAGIC        0x2BADB002
 
+#include <pmemmap.h>
+#include <bootmod.h>
+
 // === TYPES ===
 typedef struct {
        Uint32  Flags;
@@ -35,4 +39,7 @@ typedef struct {
        Uint32  Type;   //1:RAM,Else Reserved
 } __attribute__ ((packed)) tMBoot_MMapEnt;
 
+extern int     Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *Map, const int MapSize, tPAddr KStart, tPAddr KEnd);
+extern tBootModule     *Multiboot_LoadModules(tMBoot_Info *MBInfo, tVAddr MapOffset, int *ModuleCount);
+
 #endif

UCC git Repository :: git.ucc.asn.au