X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Farch%2Fx86%2Facpica.c;h=433feaac97dec9574b185c4b8837943afef6663b;hb=2462d860630674d10d554f86aa669163f6f2db6b;hp=e234649343f3b36e55aff31b5dfc5de8cb06d171;hpb=c1289cd6702ce3eadf2e26de57a2077f871139be;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/arch/x86/acpica.c b/KernelLand/Kernel/arch/x86/acpica.c index e2346493..433feaac 100644 --- a/KernelLand/Kernel/arch/x86/acpica.c +++ b/KernelLand/Kernel/arch/x86/acpica.c @@ -5,13 +5,24 @@ * acpica.c * - ACPICA Interface */ +#define ACPI_DEBUG_OUTPUT 0 +#define DEBUG 0 +#define _AcpiModuleName "Shim" +#define _COMPONENT "Acess" #include #include #include #include +#define ONEMEG (1024*1024) + +// === GLOBALS === +// - RSDP Address from uEFI +tPAddr gACPI_RSDPOverride = 0; + // === PROTOTYPES === int ACPICA_Initialise(void); +void ACPI_int_InterruptProxy(int IRQ, void *data); // === CODE === @@ -19,12 +30,40 @@ int ACPICA_Initialise(void) { ACPI_STATUS rv; + #ifdef ACPI_DEBUG_OUTPUT + AcpiDbgLevel = ACPI_DB_ALL; + #endif + rv = AcpiInitializeSubsystem(); + if( ACPI_FAILURE(rv) ) + { + Log_Error("ACPI", "AcpiInitializeSubsystem: %i", rv); + return -1; + } - // AcpiInitializeTables? + rv = AcpiInitializeTables(NULL, 16, FALSE); + if( ACPI_FAILURE(rv) ) + { + Log_Error("ACPI", "AcpiInitializeTables: %i", rv); + AcpiTerminate(); + return -1; + } + rv = AcpiLoadTables(); + if( ACPI_FAILURE(rv) ) + { + Log_Error("ACPI", "AcpiLoadTables: %i", rv); + AcpiTerminate(); + return -1; + } rv = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION); + if( ACPI_FAILURE(rv) ) + { + Log_Error("ACPI", "AcpiEnableSubsystem: %i", rv); + AcpiTerminate(); + return -1; + } return 0; } @@ -46,55 +85,130 @@ ACPI_PHYSICAL_ADDRESS AcpiOsGetRootPointer(void) { ACPI_SIZE val; ACPI_STATUS rv; - + + if( gACPI_RSDPOverride ) + return gACPI_RSDPOverride; + rv = AcpiFindRootPointer(&val); if( ACPI_FAILURE(rv) ) return 0; + LOG("val=0x%x", val); + return val; // (Or use EFI) } ACPI_STATUS AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES *PredefinedObject, ACPI_STRING *NewValue) { - return AE_NOT_IMPLEMENTED; + *NewValue = NULL; + return AE_OK; } ACPI_STATUS AcpiOsTableOverride(ACPI_TABLE_HEADER *ExisitingTable, ACPI_TABLE_HEADER **NewTable) { - return AE_NOT_IMPLEMENTED; + *NewTable = NULL; + return AE_OK; } ACPI_STATUS AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER *ExisitingTable, ACPI_PHYSICAL_ADDRESS *NewAddress, UINT32 *NewTableLength) { - return AE_NOT_IMPLEMENTED; + *NewAddress = 0; + return AE_OK; } // -- Memory Management --- +#if USE_ACESS_ACPI_CACHE +struct sACPICache +{ + Uint16 nObj; + Uint16 ObjectSize; + char *Name; + void *First; + char ObjectStates[]; +}; + ACPI_STATUS AcpiOsCreateCache(char *CacheName, UINT16 ObjectSize, UINT16 MaxDepth, ACPI_CACHE_T **ReturnCache) { - return AE_NOT_IMPLEMENTED; + tACPICache *ret; + int namelen = (CacheName ? strlen(CacheName) : 0) + 1; + LOG("CacheName=%s, ObjSize=%x, MaxDepth=%x", CacheName, ObjectSize, MaxDepth); + + if( ReturnCache == NULL || ObjectSize < 16) { + return AE_BAD_PARAMETER; + } + + namelen = (namelen + 3) & ~3; + + ret = malloc(sizeof(*ret) + MaxDepth*sizeof(char) + namelen + MaxDepth*ObjectSize); + if( !ret ) { + Log_Notice("ACPICA", "%s: malloc() fail", __func__); + return AE_NO_MEMORY; + } + + ret->nObj = MaxDepth; + ret->ObjectSize = ObjectSize; + ret->Name = (char*)(ret->ObjectStates + MaxDepth); + ret->First = ret->Name + namelen; + if( CacheName ) + strcpy(ret->Name, CacheName); + else + ret->Name[0] = 0; + memset(ret->ObjectStates, 0, sizeof(char)*MaxDepth); + + LOG("Allocated cache %p '%s' (%i x 0x%x)", ret, CacheName, MaxDepth, ObjectSize); + + *ReturnCache = ret; + + return AE_OK; } ACPI_STATUS AcpiOsDeleteCache(ACPI_CACHE_T *Cache) { if( Cache == NULL ) return AE_BAD_PARAMETER; - - return AE_NOT_IMPLEMENTED; + + free(Cache); + return AE_OK; } ACPI_STATUS AcpiOsPurgeCache(ACPI_CACHE_T *Cache) { - if( Cache == NULL ) + ENTER("pCache", Cache); + if( Cache == NULL ) { + LEAVE('i', AE_BAD_PARAMETER); return AE_BAD_PARAMETER; - - return AE_NOT_IMPLEMENTED; + } + + memset(Cache->ObjectStates, 0, sizeof(char)*Cache->nObj); + + LEAVE('i', AE_OK); + return AE_OK; } void *AcpiOsAcquireObject(ACPI_CACHE_T *Cache) { - // TODO + ENTER("pCache", Cache); + LOG("Called by %p", __builtin_return_address(0)); + for(int i = 0; i < Cache->nObj; i ++ ) + { + if( !Cache->ObjectStates[i] ) { + Cache->ObjectStates[i] = 1; + void *rv = (char*)Cache->First + i*Cache->ObjectSize; + if(!rv) { + LEAVE('n'); + return NULL; + } + memset(rv, 0, Cache->ObjectSize); + LEAVE('p', rv); + return rv; + } + } + + Log_Debug("ACPICA", "AcpiOsAcquireObject: All %i objects used in '%s'", + Cache->nObj, Cache->Name); + + LEAVE('n'); return NULL; } @@ -102,18 +216,49 @@ ACPI_STATUS AcpiOsReleaseObject(ACPI_CACHE_T *Cache, void *Object) { if( Cache == NULL || Object == NULL ) return AE_BAD_PARAMETER; - return AE_NOT_IMPLEMENTED; + ENTER("pCache pObject", Cache, Object); + + tVAddr delta = (tVAddr)Object - (tVAddr)Cache->First; + delta /= Cache->ObjectSize; + LOG("Cache=%p, delta = %i, (limit %i)", Cache, delta, Cache->nObj); + + if( delta >= Cache->nObj ) { + LEAVE('i', AE_BAD_PARAMETER); + return AE_BAD_PARAMETER; + } + + Cache->ObjectStates[delta] = 0; + + LEAVE('i', AE_OK); + return AE_OK; } +#endif void *AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS PhysicalAddress, ACPI_SIZE Length) { + if( PhysicalAddress < ONEMEG ) + return (void*)(KERNEL_BASE | PhysicalAddress); + Uint ofs = PhysicalAddress & (PAGE_SIZE-1); int npages = (ofs + Length + (PAGE_SIZE-1)) / PAGE_SIZE; - return (char*)MM_MapHWPages(PhysicalAddress, npages) + ofs; + char *maploc = (void*)MM_MapHWPages(PhysicalAddress, npages); + if(!maploc) { + LOG("Mapping %P+0x%x failed", PhysicalAddress, Length); + return NULL; + } +// MM_DumpTables(0, -1); + void *rv = maploc + ofs; + LOG("Map (%P+%i pg) to %p", PhysicalAddress, npages, rv); + return rv; } void AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Length) { + if( (tVAddr)LogicalAddress - KERNEL_BASE < ONEMEG ) + return ; + + LOG("%p", LogicalAddress); + Uint ofs = (tVAddr)LogicalAddress & (PAGE_SIZE-1); int npages = (ofs + Length + (PAGE_SIZE-1)) / PAGE_SIZE; // TODO: Validate `Length` is the same as was passed to AcpiOsMapMemory @@ -157,7 +302,7 @@ BOOLEAN AcpiOsWritable(void *Memory, ACPI_SIZE Length) // --- Threads --- ACPI_THREAD_ID AcpiOsGetThreadId(void) { - return Threads_GetTID(); + return Threads_GetTID() + 1; } ACPI_STATUS AcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Function, void *Context) @@ -190,11 +335,14 @@ void AcpiOsWaitEventsComplete(void) // --- Mutexes etc --- ACPI_STATUS AcpiOsCreateMutex(ACPI_MUTEX *OutHandle) { + LOG("()"); if( !OutHandle ) return AE_BAD_PARAMETER; tMutex *ret = calloc( sizeof(tMutex), 1 ); - if( !ret ) + if( !ret ) { + Log_Notice("ACPICA", "%s: malloc() fail", __func__); return AE_NO_MEMORY; + } ret->Name = "AcpiOsCreateMutex"; *OutHandle = ret; @@ -203,6 +351,7 @@ ACPI_STATUS AcpiOsCreateMutex(ACPI_MUTEX *OutHandle) void AcpiOsDeleteMutex(ACPI_MUTEX Handle) { + // TODO: Need `Mutex_Destroy` Mutex_Acquire(Handle); free(Handle); } @@ -224,11 +373,14 @@ void AcpiOsReleaseMutex(ACPI_MUTEX Handle) ACPI_STATUS AcpiOsCreateSemaphore(UINT32 MaxUnits, UINT32 InitialUnits, ACPI_SEMAPHORE *OutHandle) { + LOG("(MaxUnits=%i,InitialUnits=%i)", MaxUnits, InitialUnits); if( !OutHandle ) return AE_BAD_PARAMETER; tSemaphore *ret = calloc( sizeof(tSemaphore), 1 ); - if( !ret ) + if( !ret ) { + Log_Notice("ACPICA", "%s: malloc() fail", __func__); return AE_NO_MEMORY; + } Semaphore_Init(ret, InitialUnits, MaxUnits, "AcpiOsCreateSemaphore", ""); *OutHandle = ret; @@ -293,6 +445,7 @@ ACPI_STATUS AcpiOsSignalSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units) ACPI_STATUS AcpiOsCreateLock(ACPI_SPINLOCK *OutHandle) { + LOG("()"); if( !OutHandle ) return AE_BAD_PARAMETER; tShortSpinlock *lock = calloc(sizeof(tShortSpinlock), 1); @@ -361,7 +514,7 @@ ACPI_STATUS AcpiOsRemoveInterruptHandler(UINT32 InterruptLevel, ACPI_OSD_HANDLER ACPI_STATUS AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 *Value, UINT32 Width) { void *ptr; - if( Address < 1024*1024 ) { + if( Address < ONEMEG ) { ptr = (void*)(KERNEL_BASE | Address); } else { @@ -376,17 +529,19 @@ ACPI_STATUS AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 *Value, UINT3 case 64: *Value = *(Uint64*)ptr; break; } - if( Address >= 1024*1024 ) { + if( Address >= ONEMEG ) { MM_FreeTemp(ptr); } + LOG("*%P = [%i]%X", Address, Width, *Value); + return AE_OK; } ACPI_STATUS AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 Value, UINT32 Width) { void *ptr; - if( Address < 1024*1024 ) { + if( Address < ONEMEG ) { ptr = (void*)(KERNEL_BASE | Address); } else { @@ -403,7 +558,7 @@ ACPI_STATUS AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 Value, UINT3 return AE_BAD_PARAMETER; } - if( Address >= 1024*1024 ) { + if( Address >= ONEMEG ) { MM_FreeTemp(ptr); } @@ -440,11 +595,13 @@ ACPI_STATUS AcpiOsWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width) // --- PCI Configuration Space Access --- ACPI_STATUS AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 *Value, UINT32 Width) { + UNIMPLEMENTED(); return AE_NOT_IMPLEMENTED; } ACPI_STATUS AcpiOsWritePciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 Value, UINT32 Width) { + UNIMPLEMENTED(); return AE_NOT_IMPLEMENTED; } @@ -454,19 +611,19 @@ void AcpiOsPrintf(const char *Format, ...) va_list args; va_start(args, Format); - LogV(Format, args); + LogFV(Format, args); va_end(args); } void AcpiOsVprintf(const char *Format, va_list Args) { - LogV(Format, Args); + LogFV(Format, Args); } void AcpiOsRedirectOutput(void *Destination) { - // TODO: is this needed? + // TODO: Do I even need to impliment this? } // --- Miscellaneous --- @@ -492,6 +649,7 @@ ACPI_STATUS AcpiOsSignal(UINT32 Function, void *Info) ACPI_STATUS AcpiOsGetLine(char *Buffer, UINT32 BufferLength, UINT32 *BytesRead) { + UNIMPLEMENTED(); return AE_NOT_IMPLEMENTED; }