2 * Acess2 Kernel (x86 Core)
3 * - By John Hodge (thePowersGang)
11 #include <semaphore.h>
14 int ACPICA_Initialise(void);
15 void ACPI_int_InterruptProxy(int IRQ, void *data);
19 int ACPICA_Initialise(void)
23 rv = AcpiInitializeSubsystem();
24 if( ACPI_FAILURE(rv) )
26 Log_Error("ACPI", "AcpiInitializeSubsystem: %i", rv);
30 rv = AcpiInitializeTables(NULL, 16, FALSE);
31 if( ACPI_FAILURE(rv) )
33 Log_Error("ACPI", "AcpiInitializeTables: %i", rv);
37 // AcpiInitializeTables?
38 rv = AcpiLoadTables();
39 if( ACPI_FAILURE(rv) )
41 Log_Error("ACPI", "AcpiLoadTables: %i", rv);
45 rv = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION);
46 if( ACPI_FAILURE(rv) )
48 Log_Error("ACPI", "AcpiEnableSubsystem: %i", rv);
58 ACPI_STATUS AcpiOsInitialize(void)
63 ACPI_STATUS AcpiOsTerminate(void)
68 ACPI_PHYSICAL_ADDRESS AcpiOsGetRootPointer(void)
73 rv = AcpiFindRootPointer(&val);
74 if( ACPI_FAILURE(rv) )
81 ACPI_STATUS AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES *PredefinedObject, ACPI_STRING *NewValue)
84 return AE_NOT_IMPLEMENTED;
87 ACPI_STATUS AcpiOsTableOverride(ACPI_TABLE_HEADER *ExisitingTable, ACPI_TABLE_HEADER **NewTable)
90 return AE_NOT_IMPLEMENTED;
93 ACPI_STATUS AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER *ExisitingTable, ACPI_PHYSICAL_ADDRESS *NewAddress, UINT32 *NewTableLength)
96 return AE_NOT_IMPLEMENTED;
99 // -- Memory Management ---
100 ACPI_STATUS AcpiOsCreateCache(char *CacheName, UINT16 ObjectSize, UINT16 MaxDepth, ACPI_CACHE_T **ReturnCache)
103 return AE_NOT_IMPLEMENTED;
106 ACPI_STATUS AcpiOsDeleteCache(ACPI_CACHE_T *Cache)
109 return AE_BAD_PARAMETER;
112 return AE_NOT_IMPLEMENTED;
115 ACPI_STATUS AcpiOsPurgeCache(ACPI_CACHE_T *Cache)
118 return AE_BAD_PARAMETER;
121 return AE_NOT_IMPLEMENTED;
124 void *AcpiOsAcquireObject(ACPI_CACHE_T *Cache)
130 ACPI_STATUS AcpiOsReleaseObject(ACPI_CACHE_T *Cache, void *Object)
132 if( Cache == NULL || Object == NULL )
133 return AE_BAD_PARAMETER;
135 return AE_NOT_IMPLEMENTED;
138 void *AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS PhysicalAddress, ACPI_SIZE Length)
140 Uint ofs = PhysicalAddress & (PAGE_SIZE-1);
141 int npages = (ofs + Length + (PAGE_SIZE-1)) / PAGE_SIZE;
142 return (char*)MM_MapHWPages(PhysicalAddress, npages) + ofs;
145 void AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Length)
147 Uint ofs = (tVAddr)LogicalAddress & (PAGE_SIZE-1);
148 int npages = (ofs + Length + (PAGE_SIZE-1)) / PAGE_SIZE;
149 // TODO: Validate `Length` is the same as was passed to AcpiOsMapMemory
150 MM_UnmapHWPages( (tVAddr)LogicalAddress, npages);
153 ACPI_STATUS AcpiOsGetPhysicalAddress(void *LogicalAddress, ACPI_PHYSICAL_ADDRESS *PhysicalAddress)
155 if( LogicalAddress == NULL || PhysicalAddress == NULL )
156 return AE_BAD_PARAMETER;
158 tPAddr rv = MM_GetPhysAddr(LogicalAddress);
161 *PhysicalAddress = rv;
165 void *AcpiOsAllocate(ACPI_SIZE Size)
170 void AcpiOsFree(void *Memory)
175 BOOLEAN AcpiOsReadable(void *Memory, ACPI_SIZE Length)
177 return CheckMem(Memory, Length);
180 BOOLEAN AcpiOsWritable(void *Memory, ACPI_SIZE Length)
182 // TODO: Actually check if it's writable
183 return CheckMem(Memory, Length);
188 ACPI_THREAD_ID AcpiOsGetThreadId(void)
190 return Threads_GetTID();
193 ACPI_STATUS AcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Function, void *Context)
195 // TODO: Need to store currently executing functions
196 if( Function == NULL )
197 return AE_BAD_PARAMETER;
198 Proc_SpawnWorker(Function, Context);
202 void AcpiOsSleep(UINT64 Milliseconds)
204 Time_Delay(Milliseconds);
207 void AcpiOsStall(UINT32 Microseconds)
209 // TODO: need a microsleep function
210 Microseconds += (1000-1);
211 Microseconds /= 1000;
212 Time_Delay(Microseconds);
215 void AcpiOsWaitEventsComplete(void)
220 // --- Mutexes etc ---
221 ACPI_STATUS AcpiOsCreateMutex(ACPI_MUTEX *OutHandle)
224 return AE_BAD_PARAMETER;
225 tMutex *ret = calloc( sizeof(tMutex), 1 );
228 ret->Name = "AcpiOsCreateMutex";
234 void AcpiOsDeleteMutex(ACPI_MUTEX Handle)
236 Mutex_Acquire(Handle);
240 ACPI_STATUS AcpiOsAcquireMutex(ACPI_MUTEX Handle, UINT16 Timeout)
243 return AE_BAD_PARAMETER;
245 Mutex_Acquire(Handle);
250 void AcpiOsReleaseMutex(ACPI_MUTEX Handle)
252 Mutex_Release(Handle);
255 ACPI_STATUS AcpiOsCreateSemaphore(UINT32 MaxUnits, UINT32 InitialUnits, ACPI_SEMAPHORE *OutHandle)
258 return AE_BAD_PARAMETER;
259 tSemaphore *ret = calloc( sizeof(tSemaphore), 1 );
263 Semaphore_Init(ret, InitialUnits, MaxUnits, "AcpiOsCreateSemaphore", "");
268 ACPI_STATUS AcpiOsDeleteSemaphore(ACPI_SEMAPHORE Handle)
271 return AE_BAD_PARAMETER;
278 ACPI_STATUS AcpiOsWaitSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units, UINT16 Timeout)
281 return AE_BAD_PARAMETER;
286 // NOTE: Possible race condition
287 if( Semaphore_GetValue(Handle) >= Units ) {
288 Semaphore_Wait(Handle, Units);
296 while(rem && now() - start < Timeout)
298 rem -= Semaphore_Wait(Handle, rem);
302 Semaphore_Signal(Handle, Units - rem);
309 ACPI_STATUS AcpiOsSignalSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units)
312 return AE_BAD_PARAMETER;
314 // TODO: Support AE_LIMIT detection early (to avoid blocks)
317 int rv = Semaphore_Signal(Handle, Units);
324 ACPI_STATUS AcpiOsCreateLock(ACPI_SPINLOCK *OutHandle)
327 return AE_BAD_PARAMETER;
328 tShortSpinlock *lock = calloc(sizeof(tShortSpinlock), 1);
336 void AcpiOsDeleteLock(ACPI_SPINLOCK Handle)
341 ACPI_CPU_FLAGS AcpiOsAcquireLock(ACPI_SPINLOCK Handle)
347 void AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags)
352 // --- Interrupt handling ---
353 #define N_INT_LEVELS 16
354 ACPI_OSD_HANDLER gaACPI_InterruptHandlers[N_INT_LEVELS];
355 void *gaACPI_InterruptData[N_INT_LEVELS];
356 int gaACPI_InterruptHandles[N_INT_LEVELS];
358 void ACPI_int_InterruptProxy(int IRQ, void *data)
360 if( !gaACPI_InterruptHandlers[IRQ] )
362 gaACPI_InterruptHandlers[IRQ](gaACPI_InterruptData[IRQ]);
365 ACPI_STATUS AcpiOsInstallInterruptHandler(UINT32 InterruptLevel, ACPI_OSD_HANDLER Handler, void *Context)
367 if( InterruptLevel >= N_INT_LEVELS || Handler == NULL )
368 return AE_BAD_PARAMETER;
369 if( gaACPI_InterruptHandlers[InterruptLevel] )
370 return AE_ALREADY_EXISTS;
372 gaACPI_InterruptHandlers[InterruptLevel] = Handler;
373 gaACPI_InterruptData[InterruptLevel] = Context;
375 gaACPI_InterruptHandles[InterruptLevel] = IRQ_AddHandler(InterruptLevel, ACPI_int_InterruptProxy, NULL);
379 ACPI_STATUS AcpiOsRemoveInterruptHandler(UINT32 InterruptLevel, ACPI_OSD_HANDLER Handler)
381 if( InterruptLevel >= N_INT_LEVELS || Handler == NULL )
382 return AE_BAD_PARAMETER;
383 if( gaACPI_InterruptHandlers[InterruptLevel] != Handler )
385 gaACPI_InterruptHandlers[InterruptLevel] = NULL;
386 IRQ_RemHandler(gaACPI_InterruptHandles[InterruptLevel]);
390 // --- Memory Access ---
391 ACPI_STATUS AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 *Value, UINT32 Width)
394 if( Address < 1024*1024 ) {
395 ptr = (void*)(KERNEL_BASE | Address);
398 ptr = (char*)MM_MapTemp(Address) + (Address & 0xFFF);
403 case 8: *Value = *(Uint8 *)ptr; break;
404 case 16: *Value = *(Uint16*)ptr; break;
405 case 32: *Value = *(Uint32*)ptr; break;
406 case 64: *Value = *(Uint64*)ptr; break;
409 if( Address >= 1024*1024 ) {
416 ACPI_STATUS AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 Value, UINT32 Width)
419 if( Address < 1024*1024 ) {
420 ptr = (void*)(KERNEL_BASE | Address);
423 ptr = (char*)MM_MapTemp(Address) + (Address & 0xFFF);
428 case 8: *(Uint8 *)ptr = Value; break;
429 case 16: *(Uint16*)ptr = Value; break;
430 case 32: *(Uint32*)ptr = Value; break;
431 case 64: *(Uint64*)ptr = Value; break;
433 return AE_BAD_PARAMETER;
436 if( Address >= 1024*1024 ) {
443 // --- Port Input / Output ---
444 ACPI_STATUS AcpiOsReadPort(ACPI_IO_ADDRESS Address, UINT32 *Value, UINT32 Width)
448 case 8: *Value = inb(Address); break;
449 case 16: *Value = inw(Address); break;
450 case 32: *Value = ind(Address); break;
452 return AE_BAD_PARAMETER;
457 ACPI_STATUS AcpiOsWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width)
461 case 8: outb(Address, Value); break;
462 case 16: outw(Address, Value); break;
463 case 32: outd(Address, Value); break;
465 return AE_BAD_PARAMETER;
470 // --- PCI Configuration Space Access ---
471 ACPI_STATUS AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 *Value, UINT32 Width)
474 return AE_NOT_IMPLEMENTED;
477 ACPI_STATUS AcpiOsWritePciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 Value, UINT32 Width)
480 return AE_NOT_IMPLEMENTED;
483 // --- Formatted Output ---
484 void AcpiOsPrintf(const char *Format, ...)
487 va_start(args, Format);
494 void AcpiOsVprintf(const char *Format, va_list Args)
499 void AcpiOsRedirectOutput(void *Destination)
501 // TODO: is this needed?
504 // --- Miscellaneous ---
505 UINT64 AcpiOsGetTimer(void)
507 return now() * 10 * 1000;
510 ACPI_STATUS AcpiOsSignal(UINT32 Function, void *Info)
514 case ACPI_SIGNAL_FATAL: {
515 ACPI_SIGNAL_FATAL_INFO *finfo = Info;
516 Log_Error("ACPI AML", "Fatal %x %x %x", finfo->Type, finfo->Code, finfo->Argument);
518 case ACPI_SIGNAL_BREAKPOINT: {
519 Log_Notice("ACPI AML", "Breakpoint %s", Info);
525 ACPI_STATUS AcpiOsGetLine(char *Buffer, UINT32 BufferLength, UINT32 *BytesRead)
528 return AE_NOT_IMPLEMENTED;