2 * Acess2 Kernel x86 Port
3 * - By John Hodge (thePowersGang)
13 int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *Map, const int MapSize, tPAddr KStart, tPAddr KEnd)
17 ENTER("pMBInfo pMapOffset pMap iMapSize PKStart PKEnd",
18 MBInfo, MapOffset, Map, MapSize, KStart, KEnd);
20 // Check that the memory map is present
21 if( MBInfo->Flags & (1 << 6) )
23 tMBoot_MMapEnt *ent = (void*)((tVAddr)MBInfo->MMapAddr + MapOffset);
24 tMBoot_MMapEnt *last = (void*)((tVAddr)ent + MBInfo->MMapLength);
25 // Build up memory map
27 while( ent < last && nPMemMapEnts < MapSize )
29 tPMemMapEnt *nent = &Map[nPMemMapEnts];
30 if( !MM_GetPhysAddr(ent) )
31 Log_KernelPanic("MBoot", "MBoot Map entry %i addres bad (%p)",
33 LOG("%llx+%llx", ent->Base, ent->Length);
35 nent->Start = ent->Base;
36 nent->Length = ent->Length;
40 nent->Type = PMEMTYPE_FREE;
43 nent->Type = PMEMTYPE_RESERVED;
49 ent = (void*)( (tVAddr)ent + ent->Size + 4 );
53 Log_Warning("MBoot", "Memory map has >%i entries, internal version is truncated",
57 else if( MBInfo->Flags & (1 << 0) )
59 Log_Warning("MBoot", "No memory map passed, using mem_lower and mem_upper");
63 Map[0].Length = MBInfo->LowMem * 1024;
64 Map[0].Type = PMEMTYPE_FREE;
65 Map[0].NUMADomain = 0;
67 Map[1].Start = 0x100000;
68 Map[1].Length = MBInfo->HighMem * 1024;
69 Map[1].Type = PMEMTYPE_FREE;
70 Map[1].NUMADomain = 0;
74 Log_KernelPanic("MBoot", "Multiboot didn't pass memory information");
79 nPMemMapEnts = PMemMap_ValidateMap(Map, nPMemMapEnts, MapSize);
80 // TODO: Error handling
82 // Replace kernel with PMEMTYPE_USED
83 LOG("Marking kernel");
84 nPMemMapEnts = PMemMap_MarkRangeUsed(
85 Map, nPMemMapEnts, MapSize,
90 PMemMap_DumpBlocks(Map, nPMemMapEnts);
92 // Check if boot modules were passed
93 if( MBInfo->Flags & (1 << 3) )
95 // Replace modules with PMEMTYPE_USED
96 nPMemMapEnts = PMemMap_MarkRangeUsed(Map, nPMemMapEnts, MapSize,
97 MBInfo->Modules, MBInfo->ModuleCount*sizeof(tMBoot_Module)
99 LOG("MBInfo->Modules = %x", MBInfo->Modules);
100 tMBoot_Module *mods = (void*)( (tVAddr)MBInfo->Modules + MapOffset);
101 for( int i = 0; i < MBInfo->ModuleCount; i ++ )
103 LOG("&mods[%i] = %p", i, &mods[i]);
104 LOG("mods[i] = {0x%x -> 0x%x}", mods[i].Start, mods[i].End);
105 nPMemMapEnts = PMemMap_MarkRangeUsed(
106 Map, nPMemMapEnts, MapSize,
107 mods[i].Start, mods[i].End - mods[i].Start
112 // Debug - Output map
113 PMemMap_DumpBlocks(Map, nPMemMapEnts);
115 LEAVE('i', nPMemMapEnts);
119 tBootModule *Multiboot_LoadModules(tMBoot_Info *MBInfo, tVAddr MapOffset, int *ModuleCount)
121 if( !(MBInfo->Flags & (1 << 3)) ) {
123 Log_Log("Arch", "No multiboot module information passed");
127 tMBoot_Module *mods = (void*)( MBInfo->Modules + MapOffset );
128 *ModuleCount = MBInfo->ModuleCount;
129 tBootModule *ret = malloc( MBInfo->ModuleCount * sizeof(*ret) );
130 for( int i = 0; i < MBInfo->ModuleCount; i ++ )
134 Log_Log("Arch", "Multiboot Module at 0x%08x, 0x%08x bytes (String at 0x%08x)",
135 mods[i].Start, mods[i].End-mods[i].Start, mods[i].String);
137 ret[i].PBase = mods[i].Start;
138 ret[i].Size = mods[i].End - mods[i].Start;
140 // Always HW map the module data
141 ofs = mods[i].Start&0xFFF;
142 ret[i].Base = (void*)( (tVAddr)MM_MapHWPages(mods[i].Start, (ret[i].Size+ofs+0xFFF) / 0x1000)
145 // Assumes the string is < 4096 bytes long)
146 ret[i].ArgString = (char*)MM_MapHWPages(mods[i].String, 2) + (mods[i].String&0xFFF);
152 void Multiboot_FreeModules(const int ModuleCount, tBootModule *Modules)
154 for( int i = 0; i < ModuleCount; i ++ )
156 Uint ofs = Modules[i].PBase % PAGE_SIZE;
157 Uint nPages = (Modules[i].Size+ofs+PAGE_SIZE-1) / PAGE_SIZE;
158 MM_UnmapHWPages(Modules[i].Base, nPages);
159 MM_UnmapHWPages(Modules[i].ArgString, 2);
161 // TODO: handle previous freeing of this page
162 for( int pg = 0; pg < nPages; pg ++ )
163 MM_DerefPhys( Modules[i].PBase + pg*PAGE_SIZE );