5e9d76a0f1c9ad323d671acc1c926d2a3df94e10
[tpg/acess2.git] / mptable.c
1 /*
2  * Acess2 Kernel (x86 Port)
3  * - By John Hodge (thePowersGang)
4  *
5  * mptable.c
6  * - MP Table parsing
7  */
8 #include <proc_int.h>
9 #include <mptable.h>
10
11 // === PROTOTYPES ===
12 const void      *MPTable_int_LocateFloatPtr(const void *Base, size_t Size);
13
14 // === CODE ===
15 const void *MPTable_int_LocateFloatPtr(const void *Base, size_t Size)
16 {
17         const Uint32    *ptr = Base;
18
19         ASSERT( !(Size & (16-1)) );
20
21         for( ptr = Base; Size -= 16; ptr += 16/4 )
22         {
23                 if( *ptr != MPPTR_IDENT )
24                         continue ;
25                 Log("Possible table at %p", ptr);
26                 if( ByteSum(ptr, sizeof(tMPInfo)) != 0 )
27                         continue ;
28         
29                 return ptr;
30         }
31         return NULL;
32 }
33
34 const void *MPTable_LocateFloatPtr(void)
35 {
36         const void *ret;
37         // Find MP Floating Table
38         
39         // - EBDA/Last 1Kib (640KiB)
40         ret = MPTable_int_LocateFloatPtr( (void*)(KERNEL_BASE|0x9F000), 0x1000 );
41         if(ret) return ret;
42         
43         // - Last KiB (512KiB base mem)
44         ret = MPTable_int_LocateFloatPtr( (void*)(KERNEL_BASE|0x7F000), 0x1000 );
45         if(ret) return ret;
46
47         // - BIOS ROM
48         ret = MPTable_int_LocateFloatPtr( (void*)(KERNEL_BASE|0xE0000), 0x20000 );
49         if(ret) return ret;
50         
51         return NULL;
52 }
53
54 int MPTable_FillCPUs(const void *FloatPtr, tCPU *CPUs, int MaxCPUs, int *BSPIndex)
55 {
56          int    cpu_count = 0;
57         
58         const tMPInfo   *mpfloatptr = FloatPtr;
59         #if DUMP_MP_TABLE
60         Log("*mpfloatptr = %p {", mpfloatptr);
61         Log("\t.Sig = 0x%08x", mpfloatptr->Sig);
62         Log("\t.MPConfig = 0x%08x", mpfloatptr->MPConfig);
63         Log("\t.Length = 0x%02x", mpfloatptr->Length);
64         Log("\t.Version = 0x%02x", mpfloatptr->Version);
65         Log("\t.Checksum = 0x%02x", mpfloatptr->Checksum);
66         Log("\t.Features = [0x%02x,0x%02x,0x%02x,0x%02x,0x%02x]",
67                 mpfloatptr->Features[0],        mpfloatptr->Features[1],
68                 mpfloatptr->Features[2],        mpfloatptr->Features[3],
69                 mpfloatptr->Features[4]
70                 );
71         Log("}");
72         #endif          
73
74         const tMPTable *mptable = (void*)( KERNEL_BASE|mpfloatptr->MPConfig );
75         #if DUMP_MP_TABLE
76         Log("*mptable = %p {", mptable);
77         Log("\t.Sig = 0x%08x", mptable->Sig);
78         Log("\t.BaseTableLength = 0x%04x", mptable->BaseTableLength);
79         Log("\t.SpecRev = 0x%02x", mptable->SpecRev);
80         Log("\t.Checksum = 0x%02x", mptable->Checksum);
81         Log("\t.OEMID = '%8c'", mptable->OemID);
82         Log("\t.ProductID = '%8c'", mptable->ProductID);
83         Log("\t.OEMTablePtr = %p'", mptable->OEMTablePtr);
84         Log("\t.OEMTableSize = 0x%04x", mptable->OEMTableSize);
85         Log("\t.EntryCount = 0x%04x", mptable->EntryCount);
86         Log("\t.LocalAPICMemMap = 0x%08x", mptable->LocalAPICMemMap);
87         Log("\t.ExtendedTableLen = 0x%04x", mptable->ExtendedTableLen);
88         Log("\t.ExtendedTableChecksum = 0x%02x", mptable->ExtendedTableChecksum);
89         Log("}");
90         #endif
91         
92         gpMP_LocalAPIC = (void*)MM_MapHWPages(mptable->LocalAPICMemMap, 1);
93         
94         const tMPTable_Ent      *ents = mptable->Entries;
95         
96         cpu_count = 0;
97         for( int i = 0; i < mptable->EntryCount; i ++ )
98         {
99                 size_t  entSize = 4;
100                 switch( ents->Type )
101                 {
102                 case 0: // Processor
103                         entSize = 20;
104                         #if DUMP_MP_TABLE
105                         Log("%i: Processor", i);
106                         Log("\t.APICID = %i", ents->Proc.APICID);
107                         Log("\t.APICVer = 0x%02x", ents->Proc.APICVer);
108                         Log("\t.CPUFlags = 0x%02x", ents->Proc.CPUFlags);
109                         Log("\t.CPUSignature = 0x%08x", ents->Proc.CPUSignature);
110                         Log("\t.FeatureFlags = 0x%08x", ents->Proc.FeatureFlags);
111                         #endif
112                         
113                         if( !(ents->Proc.CPUFlags & 1) ) {
114                                 Log("DISABLED");
115                                 break;
116                         }
117                         
118                         // Check if there is too many processors
119                         if((cpu_count) >= MaxCPUs) {
120                                 (cpu_count) ++; // If `giNumCPUs` > MaxCPUs later, it will be clipped
121                                 break;
122                         }
123                         
124                         // Initialise CPU Info
125                         CPUs[cpu_count].APICID = ents->Proc.APICID;
126                         CPUs[cpu_count].State = 0;
127                         
128                         // Set BSP Variable
129                         if( ents->Proc.CPUFlags & 2 )
130                         {
131                                 if( *BSPIndex >= 0 )
132                                         Warning("Multiple CPUs with the BSP flag set, %i+%i", *BSPIndex, cpu_count);
133                                 else
134                                         *BSPIndex = cpu_count;
135                         }
136                         
137                         (cpu_count) ++;
138                         break;
139                 
140                 #if DUMP_MP_TABLE >= 2
141                 case 1: // Bus
142                         entSize = 8;
143                         Log("%i: Bus", i);
144                         Log("\t.ID = %i", ents->Bus.ID);
145                         Log("\t.TypeString = '%6C'", ents->Bus.TypeString);
146                         break;
147                 case 2: // I/O APIC
148                         entSize = 8;
149                         Log("%i: I/O APIC", i);
150                         Log("\t.ID = %i", ents->IOAPIC.ID);
151                         Log("\t.Version = 0x%02x", ents->IOAPIC.Version);
152                         Log("\t.Flags = 0x%02x", ents->IOAPIC.Flags);
153                         Log("\t.Addr = 0x%08x", ents->IOAPIC.Addr);
154                         break;
155                 case 3: // I/O Interrupt Assignment
156                         entSize = 8;
157                         Log("%i: I/O Interrupt Assignment", i);
158                         Log("\t.IntType = %i", ents->IOInt.IntType);
159                         Log("\t.Flags = 0x%04x", ents->IOInt.Flags);
160                         Log("\t.SourceBusID = 0x%02x", ents->IOInt.SourceBusID);
161                         Log("\t.SourceBusIRQ = 0x%02x", ents->IOInt.SourceBusIRQ);
162                         Log("\t.DestAPICID = 0x%02x", ents->IOInt.DestAPICID);
163                         Log("\t.DestAPICIRQ = 0x%02x", ents->IOInt.DestAPICIRQ);
164                         break;
165                 case 4: // Local Interrupt Assignment
166                         entSize = 8;
167                         Log("%i: Local Interrupt Assignment", i);
168                         Log("\t.IntType = %i", ents->LocalInt.IntType);
169                         Log("\t.Flags = 0x%04x", ents->LocalInt.Flags);
170                         Log("\t.SourceBusID = 0x%02x", ents->LocalInt.SourceBusID);
171                         Log("\t.SourceBusIRQ = 0x%02x", ents->LocalInt.SourceBusIRQ);
172                         Log("\t.DestLocalAPICID = 0x%02x", ents->LocalInt.DestLocalAPICID);
173                         Log("\t.DestLocalAPICIRQ = 0x%02x", ents->LocalInt.DestLocalAPICIRQ);
174                         break;
175                 default:
176                         Log("%i: Unknown (%i)", i, ents->Type);
177                         break;
178                 #endif
179                 }
180                 ents = (void*)( (Uint)ents + entSize );
181         }
182         
183         if( cpu_count > MaxCPUs )
184         {
185                 Warning("Too many CPUs detected (%i), only using %i of them", cpu_count, MaxCPUs);
186                 cpu_count = MaxCPUs;
187         }
188         
189         return cpu_count;
190 }
191

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