897c9bbbb770218541b8c65d7d1e97c91d19c9b9
[tpg/acess2.git] / KernelLand / Kernel / arch / x86 / mboot.c
1 /*
2  * Acess2 Kernel x86 Port
3  * - By John Hodge (thePowersGang)
4  *
5  * mboot.c
6  * - Multiboot Support
7  */
8 #define DEBUG   1
9 #include <acess.h>
10 #include <mboot.h>
11
12 // === CODE ===
13 int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *Map, const int MapSize, tPAddr KStart, tPAddr KEnd)
14 {
15          int    nPMemMapEnts = 0;
16         tMBoot_MMapEnt  *ent = (void*)((tVAddr)MBInfo->MMapAddr + MapOffset);
17         tMBoot_MMapEnt  *last = (void*)((tVAddr)ent + MBInfo->MMapLength);
18         
19         ENTER("pMBInfo pMapOffset pMap iMapSize PKStart PKEnd",
20                 MBInfo, MapOffset, Map, MapSize, KStart, KEnd);
21
22         // Check that the memory map is present
23         if( MBInfo->Flags & (1 << 6) )
24         {
25                 // Build up memory map
26                 nPMemMapEnts = 0;
27                 while( ent < last && nPMemMapEnts < MapSize )
28                 {
29                         tPMemMapEnt     *nent = &Map[nPMemMapEnts];
30                         if( !MM_GetPhysAddr(ent) )
31                                 Log_KernelPanic("MBoot", "MBoot Map entry %i addres bad (%p)",
32                                         nPMemMapEnts, ent);
33         
34                         nent->Start = ent->Base;
35                         nent->Length = ent->Length;
36                         switch(ent->Type)
37                         {
38                         case 1:
39                                 nent->Type = PMEMTYPE_FREE;
40                                 break;
41                         default:
42                                 nent->Type = PMEMTYPE_RESERVED;
43                                 break;
44                         }
45                         nent->NUMADomain = 0;
46                         
47                         nPMemMapEnts ++;
48                         ent = (void*)( (tVAddr)ent + ent->Size + 4 );
49                 }
50         }
51         else if( MBInfo->Flags & (1 << 0) )
52         {
53                 Log_Warning("MBoot", "No memory map passed, using mem_lower and mem_upper");
54                 nPMemMapEnts = 2;
55                 Map[0].Start = 0;
56                 Map[0].Length = MBInfo->LowMem * 1024;
57                 Map[0].Type = PMEMTYPE_FREE;
58                 Map[0].NUMADomain = 0;
59
60                 Map[1].Start = 0x100000;
61                 Map[1].Length = MBInfo->HighMem * 1024;
62                 Map[1].Type = PMEMTYPE_FREE;
63                 Map[1].NUMADomain = 0;
64         }
65         else
66         {
67                 Log_KernelPanic("MBoot", "Multiboot didn't pass memory information");
68         }
69
70         // Ensure it's valid
71         nPMemMapEnts = PMemMap_ValidateMap(Map, nPMemMapEnts, MapSize);
72         // TODO: Error handling
73
74         // Replace kernel with PMEMTYPE_USED
75         nPMemMapEnts = PMemMap_MarkRangeUsed(
76                 Map, nPMemMapEnts, MapSize,
77                 KStart, KEnd - KStart
78                 );
79
80         PMemMap_DumpBlocks(Map, nPMemMapEnts);
81
82         // Check if boot modules were passed
83         if( MBInfo->Flags & (1 << 3) )
84         {
85                 // Replace modules with PMEMTYPE_USED
86                 nPMemMapEnts = PMemMap_MarkRangeUsed(Map, nPMemMapEnts, MapSize,
87                         MBInfo->Modules, MBInfo->ModuleCount*sizeof(tMBoot_Module)
88                         );
89                 LOG("MBInfo->Modules = %x", MBInfo->Modules);
90                 tMBoot_Module *mods = (void*)( (tVAddr)MBInfo->Modules + MapOffset);
91                 for( int i = 0; i < MBInfo->ModuleCount; i ++ )
92                 {
93                         LOG("&mods[%i] = %p", i, &mods[i]);
94                         LOG("mods[i] = {0x%x -> 0x%x}", mods[i].Start, mods[i].End);
95                         nPMemMapEnts = PMemMap_MarkRangeUsed(
96                                 Map, nPMemMapEnts, MapSize,
97                                 mods[i].Start, mods[i].End - mods[i].Start
98                                 );
99                 }
100         }
101                 
102         // Debug - Output map
103         PMemMap_DumpBlocks(Map, nPMemMapEnts);
104
105         LEAVE('i', nPMemMapEnts);
106         return nPMemMapEnts;
107 }
108
109 tBootModule *Multiboot_LoadModules(tMBoot_Info *MBInfo, tVAddr MapOffset, int *ModuleCount)
110 {
111         if( !(MBInfo->Flags & (1 << 3)) ) {
112                 *ModuleCount = 0;
113                 Log_Log("Arch", "No multiboot module information passed");
114                 return NULL;
115         }
116
117         tMBoot_Module   *mods = (void*)( MBInfo->Modules + MapOffset );
118         *ModuleCount = MBInfo->ModuleCount;
119         tBootModule *ret = malloc( MBInfo->ModuleCount * sizeof(*ret) );
120         for( int i = 0; i < MBInfo->ModuleCount; i ++ )
121         {
122                  int    ofs;
123         
124                 Log_Log("Arch", "Multiboot Module at 0x%08x, 0x%08x bytes (String at 0x%08x)",
125                         mods[i].Start, mods[i].End-mods[i].Start, mods[i].String);
126         
127                 ret[i].PBase = mods[i].Start;
128                 ret[i].Size = mods[i].End - mods[i].Start;
129         
130                 // Always HW map the module data        
131                 ofs = mods[i].Start&0xFFF;
132                 ret[i].Base = (void*)( MM_MapHWPages(mods[i].Start,
133                         (ret[i].Size+ofs+0xFFF) / 0x1000
134                         ) + ofs );
135                 
136                 // Only map the string if needed
137                 if( !MM_GetPhysAddr( (void*)(mods[i].String + MapOffset) ) )
138                 {
139                         // Assumes the string is < 4096 bytes long)
140                         ret[i].ArgString = (void*)(
141                                 MM_MapHWPages(mods[i].String, 2) + (mods[i].String&0xFFF)
142                                 );
143                 }
144                 else
145                         ret[i].ArgString = (char*)(tVAddr)mods[i].String + MapOffset;
146         }
147
148         return ret;
149 }
150

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