#ifndef _IOKIT_APPLEAPIC_H
#define _IOKIT_APPLEAPIC_H
#include <IOKit/IOInterrupts.h>
#include <IOKit/IOInterruptController.h>
#if OSTYPES_K64_REV < 1
typedef long IOInterruptVectorNumber;
#endif
enum {
kOffsetIND = 0x00,
kOffsetDAT = 0x10,
kOffsetIRQPA = 0x20,
kOffsetEOIR = 0x40
};
#define IOAPIC_REG(reg) \
(*((volatile UInt32 *)(_apicBaseAddr + kOffset##reg)))
enum {
kIndexID = 0x00,
kIndexVER = 0x01,
kIndexARBID = 0x02,
kIndexBOOT = 0x03,
kIndexRTLO = 0x10,
kIndexRTHI = 0x11
};
enum {
kIDAPICIDMask = 0x0F000000,
kIDAPICIDShift = 24,
kVERMaxEntriesMask = 0x00FF0000,
kVERMaxEntriesShift = 16,
kVERPRQMask = 0x00008000,
kVERPRQShift = 15,
kVERVersionMask = 0x000000FF,
kVERVersionShift = 0,
kARBIDArbitrationIDMask = 0x0F000000,
kARBIDArbitrationIDShift = 24,
kBOOTDeliveryTypeMask = 0x00000001,
kBOOTDeliveryTypeShift = 0,
kRTLOVectorNumberMask = 0x000000FF,
kRTLOVectorNumberShift = 0,
kRTLODeliveryModeMask = 0x00000700,
kRTLODeliveryModeShift = 8,
kRTLODeliveryModeFixed = 0 << kRTLODeliveryModeShift,
kRTLODeliveryModeLowestPriority = 1 << kRTLODeliveryModeShift,
kRTLODeliveryModeSMI = 2 << kRTLODeliveryModeShift,
kRTLODeliveryModeNMI = 4 << kRTLODeliveryModeShift,
kRTLODeliveryModeINIT = 5 << kRTLODeliveryModeShift,
kRTLODeliveryModeExtINT = 7 << kRTLODeliveryModeShift,
kRTLODestinationModeMask = 0x00000800,
kRTLODestinationModeShift = 11,
kRTLODestinationModePhysical = 0 << kRTLODestinationModeShift,
kRTLODestinationModeLogical = 1 << kRTLODestinationModeShift,
kRTLODeliveryStatusMask = 0x00001000,
kRTLODeliveryStatusShift = 12,
kRTLOInputPolarityMask = 0x00002000,
kRTLOInputPolarityShift = 13,
kRTLOInputPolarityHigh = 0 << kRTLOInputPolarityShift,
kRTLOInputPolarityLow = 1 << kRTLOInputPolarityShift,
kRTLORemoteIRRMask = 0x00004000,
kRTLORemoteIRRShift = 14,
kRTLOTriggerModeMask = 0x00008000,
kRTLOTriggerModeShift = 15,
kRTLOTriggerModeEdge = 0 << kRTLOTriggerModeShift,
kRTLOTriggerModeLevel = 1 << kRTLOTriggerModeShift,
kRTLOMaskMask = 0x00010000,
kRTLOMaskShift = 16,
kRTLOMaskEnabled = 0,
kRTLOMaskDisabled = kRTLOMaskMask,
kRTHIExtendedDestinationIDMask = 0x00FF0000,
kRTHIExtendedDestinationIDShift = 16,
kRTHIDestinationMask = 0xFF000000,
kRTHIDestinationShift = 24
};
struct VectorEntry {
UInt32 l32;
UInt32 h32;
};
#define AppleAPIC AppleAPICInterruptController
class AppleAPIC : public IOInterruptController
{
OSDeclareDefaultStructors( AppleAPICInterruptController )
protected:
const OSSymbol * _handleSleepWakeFunction;
const OSSymbol * _setVectorPhysicalDestination;
IOMemoryDescriptor * _apicMemory;
IOMemoryMap * _apicMemoryMap;
IOVirtualAddress _apicBaseAddr;
IOSimpleLock * _apicLock;
IOInterruptVectorNumber _vectorBase;
VectorEntry * _vectorTable;
IOInterruptVectorNumber _vectorCount;
IOInterruptVectorNumber _destinationAddress;
UInt32 _apicIDRegister;
inline UInt32 indexRead( UInt32 index )
{
IOAPIC_REG( IND ) = index;
return IOAPIC_REG( DAT );
}
inline void indexWrite( UInt32 index, UInt32 value )
{
IOAPIC_REG( IND ) = index;
IOAPIC_REG( DAT ) = value;
}
inline void enableVectorEntry( IOInterruptVectorNumber vectorNumber )
{
IOInterruptState state;
state = IOSimpleLockLockDisableInterrupt( _apicLock );
_vectorTable[vectorNumber].l32 &= ~kRTLOMaskDisabled;
indexWrite( kIndexRTLO + vectorNumber * 2,
_vectorTable[vectorNumber].l32 );
IOSimpleLockUnlockEnableInterrupt( _apicLock, state );
}
inline void disableVectorEntry( IOInterruptVectorNumber vectorNumber )
{
IOInterruptState state;
state = IOSimpleLockLockDisableInterrupt( _apicLock );
_vectorTable[vectorNumber].l32 |= kRTLOMaskDisabled;
indexWrite( kIndexRTLO + vectorNumber * 2,
_vectorTable[vectorNumber].l32 );
IOSimpleLockUnlockEnableInterrupt( _apicLock, state );
}
void resetVectorTable( void );
void writeVectorEntry( IOInterruptVectorNumber vectorNumber );
void writeVectorEntry( IOInterruptVectorNumber vectorNumber,
VectorEntry entry );
void dumpRegisters( void );
void prepareForSleep( void );
void resumeFromSleep( void );
IOReturn setVectorPhysicalDestination( UInt32 vectorNumber,
UInt32 apicID );
virtual void free( void );
public:
virtual bool start( IOService * provider );
virtual IOReturn getInterruptType( IOService * nub,
int source,
int * interruptType );
virtual IOReturn registerInterrupt( IOService * nub,
int source,
void * target,
IOInterruptHandler handler,
void * refCon );
virtual void initVector( IOInterruptVectorNumber vectorNumber,
IOInterruptVector * vector );
virtual bool vectorCanBeShared( IOInterruptVectorNumber vectorNumber,
IOInterruptVector * vector );
virtual void enableVector( IOInterruptVectorNumber vectorNumber,
IOInterruptVector * vector );
virtual void disableVectorHard( IOInterruptVectorNumber vectorNumber,
IOInterruptVector * vector );
virtual IOReturn handleInterrupt( void * savedState,
IOService * nub,
int source );
virtual IOInterruptAction getInterruptHandlerAddress( void );
virtual IOReturn callPlatformFunction( const OSSymbol * function,
bool waitForFunction,
void * param1, void * param2,
void * param3, void * param4 );
};
#endif