historical/m0-applesillicon.git/xnu-qemu-arm64-5.1.0/roms/QemuMacDrivers/shared/MacDriverUtils.c

1 line
4.1 KiB
C
Raw Normal View History

2024-01-16 11:20:27 -06:00
/* * Various utilities for writing a MacOS "ndrv" driver, such as device-tree * helpers. These replace the various Apple sample codes whose licences * are dubious and probably not suitable for GPL code */ //#include "VideoDriverPrivate.h" //#include "VideoDriverPrototypes.h" #include "logger.h" #include "MacDriverUtils.h" /* Simplified DT properties accessors */ void *DTGetProp(RegEntryIDPtr dtNode, RegPropertyNamePtr name, RegPropertyValueSize *outSize) { OSStatus err; RegPropertyValue *v; if (!outSize) return NULL; /* Grab size so we can allocate some memory */ err = RegistryPropertyGetSize(dtNode, name, outSize); if (err) return NULL; /* Allocate */ v = PoolAllocateResident(*outSize, FALSE); if (!v) return NULL; err = RegistryPropertyGet(dtNode, name, v, outSize); if (err) return NULL; return v; } void DTFreeProp(void *v) { if (v) PoolDeallocate(v); } /* Find a BAR logical address and size */ LogicalAddress GetDeviceBARAddress(RegEntryIDPtr dtNode, PCIRegisterNumber barOffset, ByteCount *size, Boolean *isIO) { RegPropertyValueSize aasize, lasize; LogicalAddress *las = NULL; PCIAssignedAddress *aas = NULL; LogicalAddress result = 0; UInt32 i; /* First grab assigned-addresses to find the BAR */ aas = DTGetProp(dtNode, kPCIAssignedAddressProperty, &aasize); if (!aas) return NULL; aasize /= sizeof(*aas); /* Then grab AAPL,addresses to get the corresponding logical addresses */ las = DTGetProp(dtNode, kAAPLDeviceLogicalAddress, &lasize); if (!las) goto bail; lasize /= sizeof(LogicalAddress); /* Lookup BAR */ for (i = 0; i < aasize; i++) { struct PCIAssignedAddress *aa = aas + i; /* Skip config space */ if (GetPCIAddressSpaceType(aa) == kPCIConfigSpace) continue; /* Check BAR offset */ if (GetPCIRegisterNumber(aa) != barOffset) continue; /* Found it, check that it was assigned */ if (aa->size.hi == 0 && aa->size.lo == 0) { lprintf("BAR %02x not assigned !\n"); goto bail; } /* Check we have a logical for it */ if (i >= lasize) { lprintf("BAR %02x missing AAPL,address property !\n"); goto bail; } /* We don't do 64-bit, sorry... */ if (aa->size.hi) { lprintf("BAR %02x too big !\n"); goto bail; } /* Gotcha ! */ if (size) *size = aa->size.lo; if (isIO) *isIO = GetPCIAddressSpaceType(aa) == kPCIIOSpace; result = las[i]; break; } bail: DTFreeProp(aas); DTFreeProp(las); return result; } /* PCI "Command" config register address */ #define kPCIConfigCommandAddress 0x04 #define cwCommandEnableMemorySpace 0x0002 /* Enable access to PCI memory space */ OSStatus EnablePCIMemorySpace(RegEntryIDPtr dtNode) { OSStatus status; UInt16 cmd; lprintf("Reading cmd word...\n"); status = ExpMgrConfigReadWord(dtNode, (LogicalAddress)kPCIConfigCommandAddress, &cmd); if( status ) return status; lprintf("cmad word is: %04x, writing update...\n", cmd); cmd |= cwCommandEnableMemorySpace; return ExpMgrConfigWriteWord(dtNode, (LogicalAddress)kPCIConfigCommandAddress, cmd); } OSStatus SetupPCIInterrupt(RegEntryID *dtNode, IRQInfo *info, InterruptHandler handler, void *refCon) { ISTProperty *ist; RegPropertyValueSize istSize; OSStatus err; ist = DTGetProp(dtNode, kISTPropertyName, &istSize); if (!ist) { lprintf("SetupPCIInterrupt: No %s property\n", kISTPropertyName); return paramErr; } info->interruptSetMember = (*ist)[kISTChipInterruptSource]; DTFreeProp(ist); err = GetInterruptFunctions(info->interruptSetMember.setID, info->interruptSetMember.member, &info->refCon, &info->handlerFunction, &info->enableFunction, &info->disableFunction); if (err) { lprintf("SetupPCIInterrupt: Error %d getting interrupt functions\n"); return err; } err = InstallInterruptFunctions(info->interruptSetMember.setID, info->interruptSetMember.member, refCon, handler, NULL, NULL); if (err) { lprintf("SetupPCIInterru