Usermode/libc - Fix strchr and strrchr behavior
[tpg/acess2.git] / KernelLand / Kernel / arch / x86 / acpica.c
index e234649..5603add 100644 (file)
@@ -5,13 +5,24 @@
  * 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);
 
 
 // === 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,22 +216,56 @@ 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 ) {
+               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)
@@ -157,7 +305,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 +338,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 +354,7 @@ ACPI_STATUS AcpiOsCreateMutex(ACPI_MUTEX *OutHandle)
 
 void AcpiOsDeleteMutex(ACPI_MUTEX Handle)
 {
+       //  TODO: Need `Mutex_Destroy`
        Mutex_Acquire(Handle);
        free(Handle);
 }
@@ -224,11 +376,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 +448,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 +517,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 +532,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 +561,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 +598,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 +614,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 +652,7 @@ ACPI_STATUS AcpiOsSignal(UINT32 Function, void *Info)
 
 ACPI_STATUS AcpiOsGetLine(char *Buffer, UINT32 BufferLength, UINT32 *BytesRead)
 {
+       UNIMPLEMENTED();
        return AE_NOT_IMPLEMENTED;
 }
 

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