X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Farch%2Fx86%2Fmboot.c;h=726d2d23311b9698d3bf27c4e69c551aa5a860d0;hb=c1b33e91984102c1aa9a2ffe19f02c315b481726;hp=5fe4068dac6ad679a031d5fc6ba7dcb9601b5f0b;hpb=e1a5a15ff663d68e107edf0ad0a2bc878c0670d5;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/arch/x86/mboot.c b/KernelLand/Kernel/arch/x86/mboot.c index 5fe4068d..726d2d23 100644 --- a/KernelLand/Kernel/arch/x86/mboot.c +++ b/KernelLand/Kernel/arch/x86/mboot.c @@ -5,7 +5,7 @@ * mboot.c * - Multiboot Support */ -#define DEBUG 0 +#define DEBUG 1 #include #include @@ -13,57 +13,102 @@ 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 ) + // Check that the memory map is present + if( MBInfo->Flags & (1 << 6) ) { - tPMemMapEnt *nent = &Map[nPMemMapEnts]; - nent->Start = ent->Base; - nent->Length = ent->Length; - switch(ent->Type) + tMBoot_MMapEnt *ent = (void*)((tVAddr)MBInfo->MMapAddr + MapOffset); + tMBoot_MMapEnt *last = (void*)((tVAddr)ent + MBInfo->MMapLength); + // Build up memory map + nPMemMapEnts = 0; + while( ent < last && nPMemMapEnts < MapSize ) { - case 1: - nent->Type = PMEMTYPE_FREE; - break; - default: - nent->Type = PMEMTYPE_RESERVED; - break; + tPMemMapEnt *nent = &Map[nPMemMapEnts]; + if( !MM_GetPhysAddr(ent) ) + Log_KernelPanic("MBoot", "MBoot Map entry %i addres bad (%p)", + nPMemMapEnts, ent); + LOG("%llx+%llx", ent->Base, ent->Length); + + 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 ); + } + if( ent < last ) + { + Log_Warning("MBoot", "Memory map has >%i entries, internal version is truncated", + MapSize); } - nent->NUMADomain = 0; - - nPMemMapEnts ++; - ent = (void*)( (tVAddr)ent + ent->Size + 4 ); + } + else if( MBInfo->Flags & (1 << 0) ) + { + Log_Warning("MBoot", "No memory map passed, using mem_lower and mem_upper"); + ASSERT(MapSize >= 2); + nPMemMapEnts = 2; + Map[0].Start = 0; + Map[0].Length = MBInfo->LowMem * 1024; + Map[0].Type = PMEMTYPE_FREE; + Map[0].NUMADomain = 0; + + Map[1].Start = 0x100000; + Map[1].Length = MBInfo->HighMem * 1024; + Map[1].Type = PMEMTYPE_FREE; + Map[1].NUMADomain = 0; + } + else + { + Log_KernelPanic("MBoot", "Multiboot didn't pass memory information"); } // Ensure it's valid + LOG("Validating"); nPMemMapEnts = PMemMap_ValidateMap(Map, nPMemMapEnts, MapSize); // TODO: Error handling // Replace kernel with PMEMTYPE_USED + LOG("Marking kernel"); 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 ++ ) + LOG("Dumping"); + PMemMap_DumpBlocks(Map, nPMemMapEnts); + + // Check if boot modules were passed + if( MBInfo->Flags & (1 << 3) ) { - nPMemMapEnts = PMemMap_MarkRangeUsed( - Map, nPMemMapEnts, MapSize, - mods->Start, mods->End - mods->Start + // Replace modules with PMEMTYPE_USED + nPMemMapEnts = PMemMap_MarkRangeUsed(Map, nPMemMapEnts, MapSize, + MBInfo->Modules, MBInfo->ModuleCount*sizeof(tMBoot_Module) ); + LOG("MBInfo->Modules = %x", MBInfo->Modules); + tMBoot_Module *mods = (void*)( (tVAddr)MBInfo->Modules + MapOffset); + for( int i = 0; i < MBInfo->ModuleCount; i ++ ) + { + LOG("&mods[%i] = %p", i, &mods[i]); + LOG("mods[i] = {0x%x -> 0x%x}", mods[i].Start, mods[i].End); + nPMemMapEnts = PMemMap_MarkRangeUsed( + Map, nPMemMapEnts, MapSize, + mods[i].Start, mods[i].End - mods[i].Start + ); + } } - + // Debug - Output map PMemMap_DumpBlocks(Map, nPMemMapEnts); @@ -73,6 +118,12 @@ int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt * tBootModule *Multiboot_LoadModules(tMBoot_Info *MBInfo, tVAddr MapOffset, int *ModuleCount) { + if( !(MBInfo->Flags & (1 << 3)) ) { + *ModuleCount = 0; + Log_Log("Arch", "No multiboot module information passed"); + return NULL; + } + tMBoot_Module *mods = (void*)( MBInfo->Modules + MapOffset ); *ModuleCount = MBInfo->ModuleCount; tBootModule *ret = malloc( MBInfo->ModuleCount * sizeof(*ret) ); @@ -88,22 +139,29 @@ tBootModule *Multiboot_LoadModules(tMBoot_Info *MBInfo, tVAddr MapOffset, int *M // 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 ); + ret[i].Base = (void*)( (tVAddr)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; + // Assumes the string is < 4096 bytes long) + ret[i].ArgString = (char*)MM_MapHWPages(mods[i].String, 2) + (mods[i].String&0xFFF); } return ret; } +void Multiboot_FreeModules(const int ModuleCount, tBootModule *Modules) +{ + for( int i = 0; i < ModuleCount; i ++ ) + { + Uint ofs = Modules[i].PBase % PAGE_SIZE; + Uint nPages = (Modules[i].Size+ofs+PAGE_SIZE-1) / PAGE_SIZE; + MM_UnmapHWPages(Modules[i].Base, nPages); + MM_UnmapHWPages(Modules[i].ArgString, 2); + + // TODO: handle previous freeing of this page + for( int pg = 0; pg < nPages; pg ++ ) + MM_DerefPhys( Modules[i].PBase + pg*PAGE_SIZE ); + } + free(Modules); +} +