* acpica.c
* - ACPICA Interface
*/
+#define ACPI_DEBUG_OUTPUT 0
+#define DEBUG 0
+#define _AcpiModuleName "Shim"
+#define _COMPONENT "Acess"
#include <acpi.h>
#include <timers.h>
#include <mutex.h>
#include <semaphore.h>
+#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);
{
ACPI_STATUS rv;
+ #ifdef ACPI_DEBUG_OUTPUT
+ AcpiDbgLevel = ACPI_DB_ALL;
+ #endif
+
rv = AcpiInitializeSubsystem();
if( ACPI_FAILURE(rv) )
{
if( ACPI_FAILURE(rv) )
{
Log_Error("ACPI", "AcpiInitializeTables: %i", rv);
+ AcpiTerminate();
return -1;
}
- // AcpiInitializeTables?
rv = AcpiLoadTables();
if( ACPI_FAILURE(rv) )
{
Log_Error("ACPI", "AcpiLoadTables: %i", rv);
+ AcpiTerminate();
return -1;
}
if( ACPI_FAILURE(rv) )
{
Log_Error("ACPI", "AcpiEnableSubsystem: %i", rv);
+ AcpiTerminate();
return -1;
}
{
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)
{
- UNIMPLEMENTED();
- return AE_NOT_IMPLEMENTED;
+ *NewValue = NULL;
+ return AE_OK;
}
ACPI_STATUS AcpiOsTableOverride(ACPI_TABLE_HEADER *ExisitingTable, ACPI_TABLE_HEADER **NewTable)
{
- UNIMPLEMENTED();
- return AE_NOT_IMPLEMENTED;
+ *NewTable = NULL;
+ return AE_OK;
}
ACPI_STATUS AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER *ExisitingTable, ACPI_PHYSICAL_ADDRESS *NewAddress, UINT32 *NewTableLength)
{
- UNIMPLEMENTED();
- 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)
{
- UNIMPLEMENTED();
- 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;
-
- UNIMPLEMENTED();
- 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;
-
- UNIMPLEMENTED();
- 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;
}
{
if( Cache == NULL || Object == NULL )
return AE_BAD_PARAMETER;
- UNIMPLEMENTED();
- 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 ) {
+ ASSERTCR(Length, <=, ONEMEG-PhysicalAddress, NULL);
+ 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 = 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
- MM_UnmapHWPages( (tVAddr)LogicalAddress, npages);
+ MM_UnmapHWPages( LogicalAddress, npages);
}
ACPI_STATUS AcpiOsGetPhysicalAddress(void *LogicalAddress, ACPI_PHYSICAL_ADDRESS *PhysicalAddress)
// --- 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)
// --- 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;
void AcpiOsDeleteMutex(ACPI_MUTEX Handle)
{
+ // TODO: Need `Mutex_Destroy`
Mutex_Acquire(Handle);
free(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;
ACPI_STATUS AcpiOsCreateLock(ACPI_SPINLOCK *OutHandle)
{
+ LOG("()");
if( !OutHandle )
return AE_BAD_PARAMETER;
tShortSpinlock *lock = calloc(sizeof(tShortSpinlock), 1);
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 {
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 {
return AE_BAD_PARAMETER;
}
- if( Address >= 1024*1024 ) {
+ if( Address >= ONEMEG ) {
MM_FreeTemp(ptr);
}
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 ---