Merge branch 'master' of git://cadel.mutabah.net/acess2
[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                         LOG("%llx+%llx", ent->Base, ent->Length);
34         
35                         nent->Start = ent->Base;
36                         nent->Length = ent->Length;
37                         switch(ent->Type)
38                         {
39                         case 1:
40                                 nent->Type = PMEMTYPE_FREE;
41                                 break;
42                         default:
43                                 nent->Type = PMEMTYPE_RESERVED;
44                                 break;
45                         }
46                         nent->NUMADomain = 0;
47                         
48                         nPMemMapEnts ++;
49                         ent = (void*)( (tVAddr)ent + ent->Size + 4 );
50                 }
51         }
52         else if( MBInfo->Flags & (1 << 0) )
53         {
54                 Log_Warning("MBoot", "No memory map passed, using mem_lower and mem_upper");
55                 nPMemMapEnts = 2;
56                 Map[0].Start = 0;
57                 Map[0].Length = MBInfo->LowMem * 1024;
58                 Map[0].Type = PMEMTYPE_FREE;
59                 Map[0].NUMADomain = 0;
60
61                 Map[1].Start = 0x100000;
62                 Map[1].Length = MBInfo->HighMem * 1024;
63                 Map[1].Type = PMEMTYPE_FREE;
64                 Map[1].NUMADomain = 0;
65         }
66         else
67         {
68                 Log_KernelPanic("MBoot", "Multiboot didn't pass memory information");
69         }
70
71         // Ensure it's valid
72         LOG("Validating");
73         nPMemMapEnts = PMemMap_ValidateMap(Map, nPMemMapEnts, MapSize);
74         // TODO: Error handling
75
76         // Replace kernel with PMEMTYPE_USED
77         LOG("Marking kernel");
78         nPMemMapEnts = PMemMap_MarkRangeUsed(
79                 Map, nPMemMapEnts, MapSize,
80                 KStart, KEnd - KStart
81                 );
82
83         LOG("Dumping");
84         PMemMap_DumpBlocks(Map, nPMemMapEnts);
85
86         // Check if boot modules were passed
87         if( MBInfo->Flags & (1 << 3) )
88         {
89                 // Replace modules with PMEMTYPE_USED
90                 nPMemMapEnts = PMemMap_MarkRangeUsed(Map, nPMemMapEnts, MapSize,
91                         MBInfo->Modules, MBInfo->ModuleCount*sizeof(tMBoot_Module)
92                         );
93                 LOG("MBInfo->Modules = %x", MBInfo->Modules);
94                 tMBoot_Module *mods = (void*)( (tVAddr)MBInfo->Modules + MapOffset);
95                 for( int i = 0; i < MBInfo->ModuleCount; i ++ )
96                 {
97                         LOG("&mods[%i] = %p", i, &mods[i]);
98                         LOG("mods[i] = {0x%x -> 0x%x}", mods[i].Start, mods[i].End);
99                         nPMemMapEnts = PMemMap_MarkRangeUsed(
100                                 Map, nPMemMapEnts, MapSize,
101                                 mods[i].Start, mods[i].End - mods[i].Start
102                                 );
103                 }
104         }
105                 
106         // Debug - Output map
107         PMemMap_DumpBlocks(Map, nPMemMapEnts);
108
109         LEAVE('i', nPMemMapEnts);
110         return nPMemMapEnts;
111 }
112
113 tBootModule *Multiboot_LoadModules(tMBoot_Info *MBInfo, tVAddr MapOffset, int *ModuleCount)
114 {
115         if( !(MBInfo->Flags & (1 << 3)) ) {
116                 *ModuleCount = 0;
117                 Log_Log("Arch", "No multiboot module information passed");
118                 return NULL;
119         }
120
121         tMBoot_Module   *mods = (void*)( MBInfo->Modules + MapOffset );
122         *ModuleCount = MBInfo->ModuleCount;
123         tBootModule *ret = malloc( MBInfo->ModuleCount * sizeof(*ret) );
124         for( int i = 0; i < MBInfo->ModuleCount; i ++ )
125         {
126                  int    ofs;
127         
128                 Log_Log("Arch", "Multiboot Module at 0x%08x, 0x%08x bytes (String at 0x%08x)",
129                         mods[i].Start, mods[i].End-mods[i].Start, mods[i].String);
130         
131                 ret[i].PBase = mods[i].Start;
132                 ret[i].Size = mods[i].End - mods[i].Start;
133         
134                 // Always HW map the module data        
135                 ofs = mods[i].Start&0xFFF;
136                 ret[i].Base = (void*)( MM_MapHWPages(mods[i].Start,
137                         (ret[i].Size+ofs+0xFFF) / 0x1000
138                         ) + ofs );
139                 
140                 // Only map the string if needed
141                 if( !MM_GetPhysAddr( (void*)(mods[i].String + MapOffset) ) )
142                 {
143                         // Assumes the string is < 4096 bytes long)
144                         ret[i].ArgString = (void*)(
145                                 MM_MapHWPages(mods[i].String, 2) + (mods[i].String&0xFFF)
146                                 );
147                 }
148                 else
149                         ret[i].ArgString = (char*)(tVAddr)mods[i].String + MapOffset;
150         }
151
152         return ret;
153 }
154

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