Kernel - Adding (unused) ACPI code
[tpg/acess2.git] / KernelLand / Kernel / arch / x86 / acpica.c
1 /*
2  * Acess2 Kernel (x86 Core)
3  * - By John Hodge (thePowersGang)
4  *
5  * acpica.c
6  * - ACPICA Interface
7  */
8 #include <acpi.h>
9 #include <timers.h>
10 #include <mutex.h>
11 #include <semaphore.h>
12
13 // === PROTOTYPES ===
14 int     ACPICA_Initialise(void);
15
16
17 // === CODE ===
18 int ACPICA_Initialise(void)
19 {
20         ACPI_STATUS     rv;
21
22         rv = AcpiInitializeSubsystem();
23         
24         // AcpiInitializeTables?
25         rv = AcpiLoadTables();
26         
27         rv = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION);
28
29         return 0;
30 }
31
32 // ---------------
33 // --- Exports ---
34 // ---------------
35 ACPI_STATUS AcpiOsInitialize(void)
36 {
37         return AE_OK;
38 }
39
40 ACPI_STATUS AcpiOsTerminate(void)
41 {
42         return AE_OK;
43 }
44
45 ACPI_PHYSICAL_ADDRESS AcpiOsGetRootPointer(void)
46 {
47         ACPI_SIZE       val;
48         ACPI_STATUS     rv;
49         
50         rv = AcpiFindRootPointer(&val);
51         if( ACPI_FAILURE(rv) )
52                 return 0;
53
54         return val;
55         // (Or use EFI)
56 }
57
58 ACPI_STATUS AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES *PredefinedObject, ACPI_STRING *NewValue)
59 {
60         return AE_NOT_IMPLEMENTED;
61 }
62
63 ACPI_STATUS AcpiOsTableOverride(ACPI_TABLE_HEADER *ExisitingTable, ACPI_TABLE_HEADER **NewTable)
64 {
65         return AE_NOT_IMPLEMENTED;
66 }
67
68 ACPI_STATUS AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER *ExisitingTable, ACPI_PHYSICAL_ADDRESS *NewAddress, UINT32 *NewTableLength)
69 {
70         return AE_NOT_IMPLEMENTED;
71 }
72
73 // -- Memory Management ---
74 ACPI_STATUS AcpiOsCreateCache(char *CacheName, UINT16 ObjectSize, UINT16 MaxDepth, ACPI_CACHE_T **ReturnCache)
75 {
76         return AE_NOT_IMPLEMENTED;
77 }
78
79 ACPI_STATUS AcpiOsDeleteCache(ACPI_CACHE_T *Cache)
80 {
81         if( Cache == NULL )
82                 return AE_BAD_PARAMETER;
83         
84         return AE_NOT_IMPLEMENTED;
85 }
86
87 ACPI_STATUS AcpiOsPurgeCache(ACPI_CACHE_T *Cache)
88 {
89         if( Cache == NULL )
90                 return AE_BAD_PARAMETER;
91         
92         return AE_NOT_IMPLEMENTED;
93 }
94
95 void *AcpiOsAcquireObject(ACPI_CACHE_T *Cache)
96 {
97         // TODO
98         return NULL;
99 }
100
101 ACPI_STATUS AcpiOsReleaseObject(ACPI_CACHE_T *Cache, void *Object)
102 {
103         if( Cache == NULL || Object == NULL )
104                 return AE_BAD_PARAMETER;
105         return AE_NOT_IMPLEMENTED;
106 }
107
108 void *AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS PhysicalAddress, ACPI_SIZE Length)
109 {
110         Uint    ofs = PhysicalAddress & (PAGE_SIZE-1);
111         int npages = (ofs + Length + (PAGE_SIZE-1)) / PAGE_SIZE;
112         return (char*)MM_MapHWPages(PhysicalAddress, npages) + ofs;
113 }
114
115 void AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Length)
116 {
117         Uint    ofs = (tVAddr)LogicalAddress & (PAGE_SIZE-1);
118         int npages = (ofs + Length + (PAGE_SIZE-1)) / PAGE_SIZE;
119         // TODO: Validate `Length` is the same as was passed to AcpiOsMapMemory
120         MM_UnmapHWPages( (tVAddr)LogicalAddress, npages);
121 }
122
123 ACPI_STATUS AcpiOsGetPhysicalAddress(void *LogicalAddress, ACPI_PHYSICAL_ADDRESS *PhysicalAddress)
124 {
125         if( LogicalAddress == NULL || PhysicalAddress == NULL )
126                 return AE_BAD_PARAMETER;
127         
128         tPAddr  rv = MM_GetPhysAddr(LogicalAddress);
129         if( rv == 0 )
130                 return AE_ERROR;
131         *PhysicalAddress = rv;
132         return AE_OK;
133 }
134
135 void *AcpiOsAllocate(ACPI_SIZE Size)
136 {
137         return malloc(Size);
138 }
139
140 void AcpiOsFree(void *Memory)
141 {
142         return free(Memory);
143 }
144
145 BOOLEAN AcpiOsReadable(void *Memory, ACPI_SIZE Length)
146 {
147         return CheckMem(Memory, Length);
148 }
149
150 BOOLEAN AcpiOsWritable(void *Memory, ACPI_SIZE Length)
151 {
152         // TODO: Actually check if it's writable
153         return CheckMem(Memory, Length);
154 }
155
156
157 // --- Threads ---
158 ACPI_THREAD_ID AcpiOsGetThreadId(void)
159 {
160         return Threads_GetTID();
161 }
162
163 ACPI_STATUS AcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Function, void *Context)
164 {
165         // TODO: Need to store currently executing functions
166         if( Function == NULL )
167                 return AE_BAD_PARAMETER;
168         Proc_SpawnWorker(Function, Context);
169         return AE_OK;
170 }
171
172 void AcpiOsSleep(UINT64 Milliseconds)
173 {
174         Time_Delay(Milliseconds);
175 }
176
177 void AcpiOsStall(UINT32 Microseconds)
178 {
179         // TODO: need a microsleep function
180         Microseconds += (1000-1);
181         Microseconds /= 1000;
182         Time_Delay(Microseconds);
183 }
184
185 void AcpiOsWaitEventsComplete(void)
186 {
187         // TODO: 
188 }
189
190 // --- Mutexes etc ---
191 ACPI_STATUS AcpiOsCreateMutex(ACPI_MUTEX *OutHandle)
192 {
193         if( !OutHandle )
194                 return AE_BAD_PARAMETER;
195         tMutex  *ret = calloc( sizeof(tMutex), 1 );
196         if( !ret )
197                 return AE_NO_MEMORY;
198         ret->Name = "AcpiOsCreateMutex";
199         *OutHandle = ret;
200         
201         return AE_OK;
202 }
203
204 void AcpiOsDeleteMutex(ACPI_MUTEX Handle)
205 {
206         Mutex_Acquire(Handle);
207         free(Handle);
208 }
209
210 ACPI_STATUS AcpiOsAcquireMutex(ACPI_MUTEX Handle, UINT16 Timeout)
211 {
212         if( Handle == NULL )
213                 return AE_BAD_PARAMETER;
214
215         Mutex_Acquire(Handle);  
216
217         return AE_OK;
218 }
219
220 void AcpiOsReleaseMutex(ACPI_MUTEX Handle)
221 {
222         Mutex_Release(Handle);
223 }
224
225 ACPI_STATUS AcpiOsCreateSemaphore(UINT32 MaxUnits, UINT32 InitialUnits, ACPI_SEMAPHORE *OutHandle)
226 {
227         if( !OutHandle )
228                 return AE_BAD_PARAMETER;
229         tSemaphore      *ret = calloc( sizeof(tSemaphore), 1 );
230         if( !ret )
231                 return AE_NO_MEMORY;
232         
233         Semaphore_Init(ret, InitialUnits, MaxUnits, "AcpiOsCreateSemaphore", "");
234         *OutHandle = ret;
235         return AE_OK;
236 }
237
238 ACPI_STATUS AcpiOsDeleteSemaphore(ACPI_SEMAPHORE Handle)
239 {
240         if( !Handle )
241                 return AE_BAD_PARAMETER;
242
243         free(Handle);   
244
245         return AE_OK;
246 }
247
248 ACPI_STATUS AcpiOsWaitSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units, UINT16 Timeout)
249 {
250         if( !Handle )
251                 return AE_BAD_PARAMETER;
252
253         // Special case
254         if( Timeout == 0 )
255         {
256                 // NOTE: Possible race condition
257                 if( Semaphore_GetValue(Handle) >= Units ) {
258                         Semaphore_Wait(Handle, Units);
259                         return AE_OK;
260                 }
261                 return AE_TIME;
262         }
263
264         tTime   start = now();
265         UINT32  rem = Units;
266         while(rem && now() - start < Timeout)
267         {
268                 rem -= Semaphore_Wait(Handle, rem);
269         }
270
271         if( rem ) {
272                 Semaphore_Signal(Handle, Units - rem);
273                 return AE_TIME;
274         }
275
276         return AE_OK;
277 }
278
279 ACPI_STATUS AcpiOsSignalSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units)
280 {
281         if( !Handle )
282                 return AE_BAD_PARAMETER;
283
284         // TODO: Support AE_LIMIT detection early (to avoid blocks)
285
286         // NOTE: Blocks
287         int rv = Semaphore_Signal(Handle, Units);
288         if( rv != Units )
289                 return AE_LIMIT;
290         
291         return AE_OK;
292 }
293
294 ACPI_STATUS AcpiOsCreateLock(ACPI_SPINLOCK *OutHandle)
295 {
296         if( !OutHandle )
297                 return AE_BAD_PARAMETER;
298         tShortSpinlock  *lock = calloc(sizeof(tShortSpinlock), 1);
299         if( !lock )
300                 return AE_NO_MEMORY;
301         
302         *OutHandle = lock;
303         return AE_OK;
304 }
305
306 void AcpiOsDeleteLock(ACPI_SPINLOCK Handle)
307 {
308         free(Handle);
309 }
310
311 ACPI_CPU_FLAGS AcpiOsAcquireLock(ACPI_SPINLOCK Handle)
312 {
313         SHORTLOCK(Handle);
314         return 0;
315 }
316
317 void AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags)
318 {
319         SHORTREL(Handle);
320 }
321
322 // --- Interrupt handling ---
323 #define N_INT_LEVELS    16
324 ACPI_OSD_HANDLER        gaACPI_InterruptHandlers[N_INT_LEVELS];
325 void    *gaACPI_InterruptData[N_INT_LEVELS];
326  int    gaACPI_InterruptHandles[N_INT_LEVELS];
327
328 void ACPI_int_InterruptProxy(int IRQ, void *data)
329 {
330         if( !gaACPI_InterruptHandlers[IRQ] )
331                 return ;
332         gaACPI_InterruptHandlers[IRQ](gaACPI_InterruptData[IRQ]);
333 }
334
335 ACPI_STATUS AcpiOsInstallInterruptHandler(UINT32 InterruptLevel, ACPI_OSD_HANDLER Handler, void *Context)
336 {
337         if( InterruptLevel >= N_INT_LEVELS || Handler == NULL )
338                 return AE_BAD_PARAMETER;
339         if( gaACPI_InterruptHandlers[InterruptLevel] )
340                 return AE_ALREADY_EXISTS;
341
342         gaACPI_InterruptHandlers[InterruptLevel] = Handler;
343         gaACPI_InterruptData[InterruptLevel] = Context;
344
345         gaACPI_InterruptHandles[InterruptLevel] = IRQ_AddHandler(InterruptLevel, ACPI_int_InterruptProxy, NULL);
346         return AE_OK;
347 }
348
349 ACPI_STATUS AcpiOsRemoveInterruptHandler(UINT32 InterruptLevel, ACPI_OSD_HANDLER Handler)
350 {
351         if( InterruptLevel >= N_INT_LEVELS || Handler == NULL )
352                 return AE_BAD_PARAMETER;
353         if( gaACPI_InterruptHandlers[InterruptLevel] != Handler )
354                 return AE_NOT_EXIST;
355         gaACPI_InterruptHandlers[InterruptLevel] = NULL;
356         IRQ_RemHandler(gaACPI_InterruptHandles[InterruptLevel]);
357         return AE_OK;
358 }
359
360 // --- Memory Access ---
361 ACPI_STATUS AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 *Value, UINT32 Width)
362 {
363         void *ptr;
364         if( Address < 1024*1024 ) {
365                 ptr = (void*)(KERNEL_BASE | Address);
366         }
367         else {
368                 ptr = (char*)MM_MapTemp(Address) + (Address & 0xFFF);
369         }
370
371         switch(Width)
372         {
373         case 8:         *Value = *(Uint8 *)ptr; break;
374         case 16:        *Value = *(Uint16*)ptr; break;
375         case 32:        *Value = *(Uint32*)ptr; break;
376         case 64:        *Value = *(Uint64*)ptr; break;
377         }
378
379         if( Address >= 1024*1024 ) {
380                 MM_FreeTemp(ptr);
381         }
382
383         return AE_OK;
384 }
385
386 ACPI_STATUS AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 Value, UINT32 Width)
387 {
388         void *ptr;
389         if( Address < 1024*1024 ) {
390                 ptr = (void*)(KERNEL_BASE | Address);
391         }
392         else {
393                 ptr = (char*)MM_MapTemp(Address) + (Address & 0xFFF);
394         }
395
396         switch(Width)
397         {
398         case 8:         *(Uint8 *)ptr = Value;  break;
399         case 16:        *(Uint16*)ptr = Value;  break;
400         case 32:        *(Uint32*)ptr = Value;  break;
401         case 64:        *(Uint64*)ptr = Value;  break;
402         default:
403                 return AE_BAD_PARAMETER;
404         }
405
406         if( Address >= 1024*1024 ) {
407                 MM_FreeTemp(ptr);
408         }
409         
410         return AE_OK;
411 }
412
413 // --- Port Input / Output ---
414 ACPI_STATUS AcpiOsReadPort(ACPI_IO_ADDRESS Address, UINT32 *Value, UINT32 Width)
415 {
416         switch(Width)
417         {
418         case 8:         *Value = inb(Address);  break;
419         case 16:        *Value = inw(Address);  break;
420         case 32:        *Value = ind(Address);  break;
421         default:
422                 return AE_BAD_PARAMETER;
423         }
424         return AE_OK;
425 }
426
427 ACPI_STATUS AcpiOsWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width)
428 {
429         switch(Width)
430         {
431         case 8:         outb(Address, Value);   break;
432         case 16:        outw(Address, Value);   break;
433         case 32:        outd(Address, Value);   break;
434         default:
435                 return AE_BAD_PARAMETER;
436         }
437         return AE_OK;
438 }
439
440 // --- PCI Configuration Space Access ---
441 ACPI_STATUS AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 *Value, UINT32 Width)
442 {
443         return AE_NOT_IMPLEMENTED;
444 }
445
446 ACPI_STATUS AcpiOsWritePciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 Value, UINT32 Width)
447 {
448         return AE_NOT_IMPLEMENTED;
449 }
450
451 // --- Formatted Output ---
452 void AcpiOsPrintf(const char *Format, ...)
453 {
454         va_list args;
455         va_start(args, Format);
456
457         LogV(Format, args);
458
459         va_end(args);
460 }
461
462 void AcpiOsVprintf(const char *Format, va_list Args)
463 {
464         LogV(Format, Args);
465 }
466
467 void AcpiOsRedirectOutput(void *Destination)
468 {
469         // TODO: is this needed?
470 }
471
472 // --- Miscellaneous ---
473 UINT64 AcpiOsGetTimer(void)
474 {
475         return now() * 10 * 1000;
476 }
477
478 ACPI_STATUS AcpiOsSignal(UINT32 Function, void *Info)
479 {
480         switch(Function)
481         {
482         case ACPI_SIGNAL_FATAL: {
483                 ACPI_SIGNAL_FATAL_INFO  *finfo = Info;
484                 Log_Error("ACPI AML", "Fatal %x %x %x", finfo->Type, finfo->Code, finfo->Argument);
485                 break; }
486         case ACPI_SIGNAL_BREAKPOINT: {
487                 Log_Notice("ACPI AML", "Breakpoint %s", Info);
488                 break; };
489         }
490         return AE_OK;
491 }
492
493 ACPI_STATUS AcpiOsGetLine(char *Buffer, UINT32 BufferLength, UINT32 *BytesRead)
494 {
495         return AE_NOT_IMPLEMENTED;
496 }
497

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