summaryrefslogtreecommitdiffstats
path: root/sys/contrib/dev/acpica/hwregs.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/hwregs.c')
-rw-r--r--sys/contrib/dev/acpica/hwregs.c952
1 files changed, 645 insertions, 307 deletions
diff --git a/sys/contrib/dev/acpica/hwregs.c b/sys/contrib/dev/acpica/hwregs.c
index dab4533..1a04596 100644
--- a/sys/contrib/dev/acpica/hwregs.c
+++ b/sys/contrib/dev/acpica/hwregs.c
@@ -3,7 +3,7 @@
*
* Module Name: hwregs - Read/write access functions for the various ACPI
* control and status registers.
- * $Revision: 71 $
+ * $Revision: 81 $
*
******************************************************************************/
@@ -128,8 +128,8 @@
/* This matches the #defines in actypes.h. */
-NATIVE_CHAR *SleepStateTable[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_",
- "\\_S4_","\\_S4B","\\_S5_"};
+NATIVE_CHAR *SleepStateTable[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_",
+ "\\_S4_","\\_S4B","\\_S5_"};
/*******************************************************************************
@@ -145,7 +145,7 @@ NATIVE_CHAR *SleepStateTable[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_",
*
******************************************************************************/
-UINT32
+static UINT32
AcpiHwGetBitShift (
UINT32 Mask)
{
@@ -185,38 +185,42 @@ AcpiHwClearAcpiStatus (void)
DEBUG_PRINT (TRACE_IO, ("About to write %04X to %04X\n",
- ALL_FIXED_STS_BITS, (UINT16) AcpiGbl_FACP->Pm1aEvtBlk));
+ ALL_FIXED_STS_BITS,
+ (UINT16) AcpiGbl_FADT->XPm1aEvtBlk.Address));
AcpiCmAcquireMutex (ACPI_MTX_HARDWARE);
- AcpiOsOut16 (AcpiGbl_FACP->Pm1aEvtBlk, (UINT16) ALL_FIXED_STS_BITS);
+ AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS, ALL_FIXED_STS_BITS);
+
- if (AcpiGbl_FACP->Pm1bEvtBlk)
+ if (AcpiGbl_FADT->XPm1bEvtBlk.Address)
{
- AcpiOsOut16 ((UINT16) AcpiGbl_FACP->Pm1bEvtBlk,
+ AcpiOsOut16 ((ACPI_IO_ADDRESS) AcpiGbl_FADT->XPm1bEvtBlk.Address,
(UINT16) ALL_FIXED_STS_BITS);
}
/* now clear the GPE Bits */
- if (AcpiGbl_FACP->Gpe0BlkLen)
+ if (AcpiGbl_FADT->Gpe0BlkLen)
{
- GpeLength = (UINT16) DIV_2 (AcpiGbl_FACP->Gpe0BlkLen);
+ GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe0BlkLen);
for (Index = 0; Index < GpeLength; Index++)
{
- AcpiOsOut8 ((AcpiGbl_FACP->Gpe0Blk + Index), (UINT8) 0xff);
+ AcpiOsOut8 ((ACPI_IO_ADDRESS) (AcpiGbl_FADT->XGpe0Blk.Address + Index),
+ (UINT8) 0xff);
}
}
- if (AcpiGbl_FACP->Gpe1BlkLen)
+ if (AcpiGbl_FADT->Gpe1BlkLen)
{
- GpeLength = (UINT16) DIV_2 (AcpiGbl_FACP->Gpe1BlkLen);
+ GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe1BlkLen);
for (Index = 0; Index < GpeLength; Index++)
{
- AcpiOsOut8 ((AcpiGbl_FACP->Gpe1Blk + Index), (UINT8) 0xff);
+ AcpiOsOut8 ((ACPI_IO_ADDRESS) (AcpiGbl_FADT->XGpe1Blk.Address + Index),
+ (UINT8) 0xff);
}
}
@@ -332,23 +336,23 @@ AcpiHwObtainSleepTypeRegisterData (
/*******************************************************************************
*
- * FUNCTION: AcpiHwRegisterAccess
+ * FUNCTION: AcpiHwRegisterBitAccess
*
* PARAMETERS: ReadWrite - Either ACPI_READ or ACPI_WRITE.
* UseLock - Lock the hardware
- * RegisterId - index of ACPI register to access
+ * RegisterId - index of ACPI Register to access
* Value - (only used on write) value to write to the
- * register. Shifted all the way right.
+ * Register. Shifted all the way right.
*
- * RETURN: Value written to or read from specified register. This value
+ * RETURN: Value written to or read from specified Register. This value
* is shifted all the way right.
*
- * DESCRIPTION: Generic ACPI register read/write function.
+ * DESCRIPTION: Generic ACPI Register read/write function.
*
******************************************************************************/
UINT32
-AcpiHwRegisterAccess (
+AcpiHwRegisterBitAccess (
NATIVE_UINT ReadWrite,
BOOLEAN UseLock,
UINT32 RegisterId,
@@ -357,10 +361,8 @@ AcpiHwRegisterAccess (
UINT32 RegisterValue = 0;
UINT32 Mask = 0;
UINT32 Value = 0;
- ACPI_IO_ADDRESS GpeReg = 0;
-
- FUNCTION_TRACE ("HwRegisterIO");
+ FUNCTION_TRACE ("HwRegisterBitAccess");
if (ReadWrite == ACPI_WRITE)
@@ -372,224 +374,128 @@ AcpiHwRegisterAccess (
va_end (marker);
}
- /*
- * TBD: [Restructure] May want to split the AcpiEvent code and the
- * Control code
- */
+ if (ACPI_MTX_LOCK == UseLock) {
+ AcpiCmAcquireMutex (ACPI_MTX_HARDWARE);
+ }
/*
* Decode the Register ID
+ * Register id = Register block id | bit id
+ *
+ * Check bit id to fine locate Register offset.
+ * check Mask to determine Register offset, and then read-write.
*/
- switch (RegisterId & REGISTER_BLOCK_MASK)
+ switch (REGISTER_BLOCK_ID(RegisterId))
{
- case PM1_EVT:
+ case PM1_STS:
- if (RegisterId < TMR_EN)
+ switch (RegisterId)
{
- /* status register */
-
- if (ACPI_MTX_LOCK == UseLock)
- {
- AcpiCmAcquireMutex (ACPI_MTX_HARDWARE);
- }
-
+ case TMR_STS:
+ Mask = TMR_STS_MASK;
+ break;
- RegisterValue = (UINT32) AcpiOsIn16 (AcpiGbl_FACP->Pm1aEvtBlk);
- DEBUG_PRINT (TRACE_IO, ("PM1a status: Read 0x%X from 0x%X\n",
- RegisterValue, AcpiGbl_FACP->Pm1aEvtBlk));
+ case BM_STS:
+ Mask = BM_STS_MASK;
+ break;
- if (AcpiGbl_FACP->Pm1bEvtBlk)
- {
- RegisterValue |= (UINT32) AcpiOsIn16 (AcpiGbl_FACP->Pm1bEvtBlk);
- DEBUG_PRINT (TRACE_IO, ("PM1b status: Read 0x%X from 0x%X\n",
- RegisterValue, AcpiGbl_FACP->Pm1bEvtBlk));
- }
+ case GBL_STS:
+ Mask = GBL_STS_MASK;
+ break;
- switch (RegisterId)
- {
- case TMR_STS:
- Mask = TMR_STS_MASK;
- break;
+ case PWRBTN_STS:
+ Mask = PWRBTN_STS_MASK;
+ break;
- case BM_STS:
- Mask = BM_STS_MASK;
- break;
+ case SLPBTN_STS:
+ Mask = SLPBTN_STS_MASK;
+ break;
- case GBL_STS:
- Mask = GBL_STS_MASK;
- break;
+ case RTC_STS:
+ Mask = RTC_STS_MASK;
+ break;
- case PWRBTN_STS:
- Mask = PWRBTN_STS_MASK;
- break;
+ case WAK_STS:
+ Mask = WAK_STS_MASK;
+ break;
- case SLPBTN_STS:
- Mask = SLPBTN_STS_MASK;
- break;
+ default:
+ Mask = 0;
+ break;
+ }
- case RTC_STS:
- Mask = RTC_STS_MASK;
- break;
+ RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_STS);
- case WAK_STS:
- Mask = WAK_STS_MASK;
- break;
+ if (ReadWrite == ACPI_WRITE)
+ {
+ /*
+ * Status Registers are different from the rest. Clear by
+ * writing 1, writing 0 has no effect. So, the only relevent
+ * information is the single bit we're interested in, all
+ * others should be written as 0 so they will be left
+ * unchanged
+ */
- default:
- Mask = 0;
- break;
- }
+ Value <<= AcpiHwGetBitShift (Mask);
+ Value &= Mask;
- if (ReadWrite == ACPI_WRITE)
+ if (Value)
{
- /*
- * Status registers are different from the rest. Clear by
- * writing 1, writing 0 has no effect. So, the only relevent
- * information is the single bit we're interested in, all
- * others should be written as 0 so they will be left
- * unchanged
- */
-
- Value <<= AcpiHwGetBitShift (Mask);
- Value &= Mask;
-
- if (Value)
- {
- DEBUG_PRINT (TRACE_IO,
- ("About to write 0x%X to 0x%X\n", Value,
- AcpiGbl_FACP->Pm1aEvtBlk));
-
- AcpiOsOut16 (AcpiGbl_FACP->Pm1aEvtBlk, (UINT16) Value);
-
- if (AcpiGbl_FACP->Pm1bEvtBlk)
- {
- AcpiOsOut16 (AcpiGbl_FACP->Pm1bEvtBlk, (UINT16) Value);
- }
-
- RegisterValue = 0;
- }
- }
+ AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS, (UINT16) Value);
- if (ACPI_MTX_LOCK == UseLock)
- {
- AcpiCmReleaseMutex (ACPI_MTX_HARDWARE);
+ RegisterValue = 0;
}
}
- else
- {
- /* enable register */
-
- if (ACPI_MTX_LOCK == UseLock)
- {
- AcpiCmAcquireMutex (ACPI_MTX_HARDWARE);
- }
-
- RegisterValue = (UINT32) AcpiOsIn16 (AcpiGbl_FACP->Pm1aEvtBlk +
- DIV_2 (AcpiGbl_FACP->Pm1EvtLen));
-
- DEBUG_PRINT (TRACE_IO, ("PM1a enable: Read 0x%X from 0x%X\n",
- RegisterValue, (AcpiGbl_FACP->Pm1aEvtBlk +
- DIV_2 (AcpiGbl_FACP->Pm1EvtLen))));
+ break;
- if (AcpiGbl_FACP->Pm1bEvtBlk)
- {
- RegisterValue |= (UINT32) AcpiOsIn16 (AcpiGbl_FACP->Pm1bEvtBlk +
- DIV_2 (AcpiGbl_FACP->Pm1EvtLen));
- DEBUG_PRINT (TRACE_IO, ("PM1b enable: Read 0x%X from 0x%X\n",
- RegisterValue, (AcpiGbl_FACP->Pm1bEvtBlk +
- DIV_2 (AcpiGbl_FACP->Pm1EvtLen))));
- }
+ case PM1_EN:
- switch (RegisterId)
- {
- case TMR_EN:
- Mask = TMR_EN_MASK;
- break;
-
- case GBL_EN:
- Mask = GBL_EN_MASK;
- break;
+ switch (RegisterId)
+ {
+ case TMR_EN:
+ Mask = TMR_EN_MASK;
+ break;
- case PWRBTN_EN:
- Mask = PWRBTN_EN_MASK;
- break;
+ case GBL_EN:
+ Mask = GBL_EN_MASK;
+ break;
- case SLPBTN_EN:
- Mask = SLPBTN_EN_MASK;
- break;
+ case PWRBTN_EN:
+ Mask = PWRBTN_EN_MASK;
+ break;
- case RTC_EN:
- Mask = RTC_EN_MASK;
- break;
+ case SLPBTN_EN:
+ Mask = SLPBTN_EN_MASK;
+ break;
- default:
- Mask = 0;
- break;
- }
+ case RTC_EN:
+ Mask = RTC_EN_MASK;
+ break;
- if (ReadWrite == ACPI_WRITE)
- {
- RegisterValue &= ~Mask;
- Value <<= AcpiHwGetBitShift (Mask);
- Value &= Mask;
- RegisterValue |= Value;
-
- DEBUG_PRINT (TRACE_IO,
- ("About to write %04X to %04X\n", RegisterValue,
- (AcpiGbl_FACP->Pm1aEvtBlk +
- DIV_2 (AcpiGbl_FACP->Pm1EvtLen))));
-
- AcpiOsOut16 ((AcpiGbl_FACP->Pm1aEvtBlk +
- DIV_2 (AcpiGbl_FACP->Pm1EvtLen)),
- (UINT16) RegisterValue);
-
- if (AcpiGbl_FACP->Pm1bEvtBlk)
- {
- AcpiOsOut16 ((AcpiGbl_FACP->Pm1bEvtBlk +
- DIV_2 (AcpiGbl_FACP->Pm1EvtLen)),
- (UINT16) RegisterValue);
- }
- }
- if(ACPI_MTX_LOCK == UseLock)
- {
- AcpiCmReleaseMutex (ACPI_MTX_HARDWARE);
- }
+ default:
+ Mask = 0;
+ break;
}
- break;
-
-
- case PM1_CONTROL:
- RegisterValue = 0;
+ RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_EN);
- if (ACPI_MTX_LOCK == UseLock)
+ if (ReadWrite == ACPI_WRITE)
{
- AcpiCmAcquireMutex (ACPI_MTX_HARDWARE);
+ RegisterValue &= ~Mask;
+ Value <<= AcpiHwGetBitShift (Mask);
+ Value &= Mask;
+ RegisterValue |= Value;
+
+ AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_EN, (UINT16) RegisterValue);
}
- if (RegisterId != SLP_TYPE_B)
- {
- /*
- * SLP_TYPx registers are written differently
- * than any other control registers with
- * respect to A and B registers. The value
- * for A may be different than the value for B
- */
+ break;
- RegisterValue = (UINT32) AcpiOsIn16 (AcpiGbl_FACP->Pm1aCntBlk);
- DEBUG_PRINT (TRACE_IO, ("PM1a control: Read 0x%X from 0x%X\n",
- RegisterValue, AcpiGbl_FACP->Pm1aCntBlk));
- }
- if (AcpiGbl_FACP->Pm1bCntBlk && RegisterId != (UINT32) SLP_TYPE_A)
- {
- RegisterValue |= (UINT32) AcpiOsIn16 (AcpiGbl_FACP->Pm1bCntBlk);
- DEBUG_PRINT (TRACE_IO, ("PM1b control: Read 0x%X from 0x%X\n",
- RegisterValue, AcpiGbl_FACP->Pm1bCntBlk));
- }
+ case PM1_CONTROL:
switch (RegisterId)
{
@@ -619,6 +525,16 @@ AcpiHwRegisterAccess (
break;
}
+
+ /*
+ * Read the PM1 Control register.
+ * Note that at this level, the fact that there are actually TWO
+ * registers (A and B) and that B may not exist, are abstracted.
+ */
+ RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_CONTROL);
+
+ DEBUG_PRINT (TRACE_IO, ("PM1 control: Read 0x%X\n", RegisterValue));
+
if (ReadWrite == ACPI_WRITE)
{
RegisterValue &= ~Mask;
@@ -627,56 +543,20 @@ AcpiHwRegisterAccess (
RegisterValue |= Value;
/*
- * SLP_TYPE_x registers are written differently
- * than any other control registers with
- * respect to A and B registers. The value
+ * SLP_TYPE_x Registers are written differently
+ * than any other control Registers with
+ * respect to A and B Registers. The value
* for A may be different than the value for B
*/
- if (RegisterId != SLP_TYPE_B)
- {
- if (Mask == SLP_EN_MASK)
- {
- disable(); /* disable interrupts */
- }
-
- AcpiOsOut16 (AcpiGbl_FACP->Pm1aCntBlk, (UINT16) RegisterValue);
-
- if (Mask == SLP_EN_MASK)
- {
- /*
- * Enable interrupts, the SCI handler is likely going to
- * be invoked as soon as interrupts are enabled, since gpe's
- * and most fixed resume events also generate SCI's.
- */
- enable();
- }
- }
-
- if (AcpiGbl_FACP->Pm1bCntBlk && RegisterId != (UINT32) SLP_TYPE_A)
- {
- AcpiOsOut16 (AcpiGbl_FACP->Pm1bCntBlk, (UINT16) RegisterValue);
- }
- }
-
- if (ACPI_MTX_LOCK == UseLock)
- {
- AcpiCmReleaseMutex (ACPI_MTX_HARDWARE);
+ AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
+ PM1_CONTROL, (UINT16) RegisterValue);
}
break;
case PM2_CONTROL:
- if (ACPI_MTX_LOCK == UseLock)
- {
- AcpiCmAcquireMutex (ACPI_MTX_HARDWARE);
- }
-
- RegisterValue = (UINT32) AcpiOsIn16 (AcpiGbl_FACP->Pm2CntBlk);
- DEBUG_PRINT (TRACE_IO, ("PM2 control: Read 0x%X from 0x%X\n",
- RegisterValue, AcpiGbl_FACP->Pm2CntBlk));
-
switch (RegisterId)
{
case ARB_DIS:
@@ -688,6 +568,11 @@ AcpiHwRegisterAccess (
break;
}
+ RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL);
+
+ DEBUG_PRINT (TRACE_IO, ("PM2 control: Read 0x%X from 0x%X\n",
+ RegisterValue, AcpiGbl_FADT->XPm2CntBlk.Address));
+
if (ReadWrite == ACPI_WRITE)
{
RegisterValue &= ~Mask;
@@ -697,92 +582,63 @@ AcpiHwRegisterAccess (
DEBUG_PRINT (TRACE_IO,
("About to write %04X to %04X\n", RegisterValue,
- AcpiGbl_FACP->Pm2CntBlk));
-
- AcpiOsOut16 (AcpiGbl_FACP->Pm2CntBlk, (UINT16) RegisterValue);
- }
+ AcpiGbl_FADT->XPm2CntBlk.Address));
- if (ACPI_MTX_LOCK == UseLock)
- {
- AcpiCmReleaseMutex (ACPI_MTX_HARDWARE);
+ AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
+ PM2_CONTROL, (UINT8) (RegisterValue));
}
break;
case PM_TIMER:
- RegisterValue = AcpiOsIn32 (AcpiGbl_FACP->PmTmrBlk);
+ Mask = TMR_VAL_MASK;
+ RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
+ PM_TIMER);
DEBUG_PRINT (TRACE_IO, ("PM_TIMER: Read 0x%X from 0x%X\n",
- RegisterValue, AcpiGbl_FACP->PmTmrBlk));
+ RegisterValue, AcpiGbl_FADT->XPmTmrBlk.Address));
- Mask = ACPI_UINT32_MAX;
break;
case GPE1_EN_BLOCK:
-
- GpeReg = (AcpiGbl_FACP->Gpe1Blk + AcpiGbl_FACP->Gpe1Base) +
- (GpeReg + (DIV_2 (AcpiGbl_FACP->Gpe1BlkLen)));
-
-
case GPE1_STS_BLOCK:
-
- if (!GpeReg)
- {
- GpeReg = (AcpiGbl_FACP->Gpe1Blk + AcpiGbl_FACP->Gpe1Base);
- }
-
-
case GPE0_EN_BLOCK:
-
- if (!GpeReg)
- {
- GpeReg = AcpiGbl_FACP->Gpe0Blk + DIV_2 (AcpiGbl_FACP->Gpe0BlkLen);
- }
-
-
case GPE0_STS_BLOCK:
- if (!GpeReg)
- {
- GpeReg = AcpiGbl_FACP->Gpe0Blk;
- }
-
- /* Determine the bit to be accessed */
+ /* Determine the bit to be accessed
+ *
+ * (UINT32) RegisterId:
+ * 31 24 16 8 0
+ * +--------+--------+--------+--------+
+ * | gpe_block_id | gpe_bit_number |
+ * +--------+--------+--------+--------+
+ *
+ * gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK
+ * gpe_bit_number is relative from the gpe_block (0x00~0xFF)
+ */
- Mask = (((UINT32) RegisterId) & BIT_IN_REGISTER_MASK);
- Mask = 1 << (Mask-1);
+ Mask = REGISTER_BIT_ID(RegisterId); /* gpe_bit_number */
+ RegisterId = REGISTER_BLOCK_ID(RegisterId) | (Mask >> 3);
+ Mask = AcpiGbl_DecodeTo8bit [Mask % 8];
/*
* The base address of the GPE 0 Register Block
* Plus 1/2 the length of the GPE 0 Register Block
- * The enable register is the register following the Status Register
- * and each register is defined as 1/2 of the total Register Block
+ * The enable Register is the Register following the Status Register
+ * and each Register is defined as 1/2 of the total Register Block
*/
/*
* This sets the bit within EnableBit that needs to be written to
- * the register indicated in Mask to a 1, all others are 0
+ * the Register indicated in Mask to a 1, all others are 0
*/
- if (Mask > LOW_BYTE)
- {
- /* Shift the value 1 byte to the right and add 1 to the register */
-
- Mask >>= ONE_BYTE;
- GpeReg++;
- }
-
/* Now get the current Enable Bits in the selected Reg */
- if(ACPI_MTX_LOCK == UseLock)
- {
- AcpiCmAcquireMutex (ACPI_MTX_HARDWARE);
- }
-
- RegisterValue = (UINT32) AcpiOsIn8 (GpeReg);
+ RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, RegisterId);
DEBUG_PRINT (TRACE_IO, ("GPE Enable bits: Read 0x%X from 0x%X\n",
- RegisterValue, GpeReg));
+ RegisterValue, RegisterId));
if (ReadWrite == ACPI_WRITE)
{
@@ -792,30 +648,30 @@ AcpiHwRegisterAccess (
RegisterValue |= Value;
/* This write will put the Action state into the General Purpose */
-
/* Enable Register indexed by the value in Mask */
DEBUG_PRINT (TRACE_IO, ("About to write %04X to %04X\n",
- RegisterValue, GpeReg));
-
- AcpiOsOut8 (GpeReg, (UINT8) RegisterValue);
- RegisterValue = (UINT32) AcpiOsIn8 (GpeReg);
- }
-
- if(ACPI_MTX_LOCK == UseLock)
- {
- AcpiCmReleaseMutex (ACPI_MTX_HARDWARE);
+ RegisterValue, RegisterId));
+ AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
+ RegisterId, (UINT8) RegisterValue);
+ RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, RegisterId);
}
break;
+ case SMI_CMD_BLOCK:
case PROCESSOR_BLOCK:
+ /* not used */
default:
Mask = 0;
break;
}
+ if (ACPI_MTX_LOCK == UseLock) {
+ AcpiCmReleaseMutex (ACPI_MTX_HARDWARE);
+ }
+
RegisterValue &= Mask;
RegisterValue >>= AcpiHwGetBitShift (Mask);
@@ -823,3 +679,485 @@ AcpiHwRegisterAccess (
DEBUG_PRINT (TRACE_IO, ("Register I/O: returning 0x%X\n", RegisterValue));
return_VALUE (RegisterValue);
}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwRegisterRead
+ *
+ * PARAMETERS: UseLock - Mutex hw access.
+ * RegisterId - RegisterID + Offset.
+ *
+ * RETURN: Value read or written.
+ *
+ * DESCRIPTION: Acpi register read function. Registers are read at the
+ * given offset.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiHwRegisterRead (
+ BOOLEAN UseLock,
+ UINT32 RegisterId)
+{
+ UINT32 Value = 0;
+ UINT32 Offset = REGISTER_OFFSET (RegisterId);
+ UINT32 BankOffset;
+
+ FUNCTION_TRACE ("AcpiHwRegisterRead");
+
+ if (ACPI_MTX_LOCK == UseLock)
+ {
+ AcpiCmAcquireMutex (ACPI_MTX_HARDWARE);
+ }
+
+
+ switch (REGISTER_BLOCK_ID(RegisterId))
+ {
+ case PM1_STS: /* 16-bit access */
+
+ Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, Offset);
+ Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, Offset);
+ break;
+
+
+ case PM1_EN: /* 16-bit access*/
+
+ BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen);
+ Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset + Offset);
+ Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset + Offset);
+ break;
+
+
+ case PM1_CONTROL: /* 16-bit access */
+
+ if (RegisterId != SLP_TYPE_B)
+ {
+ Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aCntBlk, 0);
+ }
+
+ if (RegisterId != SLP_TYPE_A)
+ {
+ Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bCntBlk, 0);
+ }
+ break;
+
+
+ case PM2_CONTROL: /* 8-bit access */
+
+ Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XPm2CntBlk, Offset);
+ break;
+
+
+ case PM_TIMER: /* 32-bit access */
+
+ Value = AcpiHwLowLevelRead (32, &AcpiGbl_FADT->XPmTmrBlk, Offset);
+ break;
+
+
+ case GPE0_STS_BLOCK: /* 8-bit access */
+
+ Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, Offset);
+ break;
+
+
+ case GPE0_EN_BLOCK: /* 8-bit access */
+
+ BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen);
+ Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset + Offset);
+ break;
+
+
+ case GPE1_STS_BLOCK: /* 8-bit access */
+
+ Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, Offset);
+ break;
+
+
+ case GPE1_EN_BLOCK: /* 8-bit access */
+
+ BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen);
+ Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset + Offset);
+ break;
+
+
+ case SMI_CMD_BLOCK: /* 8bit */
+
+ Value = (UINT32) AcpiOsIn8 (AcpiGbl_FADT->SmiCmd);
+ break;
+
+
+ default:
+ Value = 0;
+ break;
+ }
+
+
+ if (ACPI_MTX_LOCK == UseLock)
+ {
+ AcpiCmReleaseMutex (ACPI_MTX_HARDWARE);
+ }
+
+ return_VALUE (Value);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwRegisterWrite
+ *
+ * PARAMETERS: UseLock - Mutex hw access.
+ * RegisterId - RegisterID + Offset.
+ *
+ * RETURN: Value read or written.
+ *
+ * DESCRIPTION: Acpi register Write function. Registers are written at the
+ * given offset.
+ *
+ ******************************************************************************/
+
+void
+AcpiHwRegisterWrite (
+ BOOLEAN UseLock,
+ UINT32 RegisterId,
+ UINT32 Value)
+{
+ UINT32 Offset = REGISTER_OFFSET (RegisterId);
+ UINT32 BankOffset;
+
+ FUNCTION_TRACE ("AcpiHwRegisterWrite");
+
+
+ if (ACPI_MTX_LOCK == UseLock)
+ {
+ AcpiCmAcquireMutex (ACPI_MTX_HARDWARE);
+ }
+
+
+ switch (REGISTER_BLOCK_ID (RegisterId))
+ {
+ case PM1_STS: /* 16-bit access */
+
+ AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, Offset);
+ AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, Offset);
+ break;
+
+
+ case PM1_EN: /* 16-bit access*/
+
+ BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen);
+ AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset + Offset);
+ AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset + Offset);
+ break;
+
+
+ case PM1_CONTROL: /* 16-bit access */
+
+ /*
+ * If SLP_TYP_A or SLP_TYP_B, only write to one reg block.
+ * Otherwise, write to both.
+ */
+ if (RegisterId == SLP_TYPE_A)
+ {
+ AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, Offset);
+ }
+ else if (RegisterId == SLP_TYPE_B)
+ {
+ AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, Offset);
+ }
+ else
+ {
+ /* disable/re-enable interrupts if sleeping */
+ if (RegisterId == SLP_EN)
+ {
+ disable();
+ }
+
+ AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, Offset);
+ AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, Offset);
+
+ if (RegisterId == SLP_EN)
+ {
+ enable();
+ }
+ }
+
+ break;
+
+
+ case PM2_CONTROL: /* 8-bit access */
+
+ AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XPm2CntBlk, Offset);
+ break;
+
+
+ case PM_TIMER: /* 32-bit access */
+
+ AcpiHwLowLevelWrite (32, Value, &AcpiGbl_FADT->XPmTmrBlk, Offset);
+ break;
+
+
+ case GPE0_STS_BLOCK: /* 8-bit access */
+
+ AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, Offset);
+ break;
+
+
+ case GPE0_EN_BLOCK: /* 8-bit access */
+
+ BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen);
+ AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset + Offset);
+ break;
+
+
+ case GPE1_STS_BLOCK: /* 8-bit access */
+
+ AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, Offset);
+ break;
+
+
+ case GPE1_EN_BLOCK: /* 8-bit access */
+
+ BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen);
+ AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset + Offset);
+ break;
+
+
+ case SMI_CMD_BLOCK: /* 8bit */
+
+ /* For 2.0, SMI_CMD is always in IO space */
+ /* TBD: what about 1.0? 0.71? */
+
+ AcpiOsOut8 (AcpiGbl_FADT->SmiCmd, (UINT8) Value);
+ break;
+
+
+ default:
+ Value = 0;
+ break;
+ }
+
+
+ if (ACPI_MTX_LOCK == UseLock)
+ {
+ AcpiCmReleaseMutex (ACPI_MTX_HARDWARE);
+ }
+
+ return_VOID;
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwLowLevelRead
+ *
+ * PARAMETERS: Register - GAS register structure
+ * Offset - Offset from the base address in the GAS
+ * Width - 8, 16, or 32
+ *
+ * RETURN: Value read
+ *
+ * DESCRIPTION: Read from either memory, IO, or PCI config space.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiHwLowLevelRead (
+ UINT32 Width,
+ ACPI_GAS *Reg,
+ UINT32 Offset)
+{
+ UINT32 Value = 0;
+ ACPI_PHYSICAL_ADDRESS MemAddress;
+ ACPI_IO_ADDRESS IoAddress;
+ UINT32 PciRegister;
+ UINT32 PciDevFunc;
+
+
+ /*
+ * Must have a valid pointer to a GAS structure, and
+ * a non-zero address within
+ */
+ if ((!Reg) ||
+ (!Reg->Address))
+ {
+ return 0;
+ }
+
+
+ /*
+ * Three address spaces supported:
+ * Memory, Io, or PCI config.
+ */
+
+ switch (Reg->AddressSpaceId)
+ {
+ case ADDRESS_SPACE_SYSTEM_MEMORY:
+
+ MemAddress = (ACPI_PHYSICAL_ADDRESS) Reg->Address + Offset;
+
+ switch (Width)
+ {
+ case 8:
+ Value = AcpiOsMemIn8 (MemAddress);
+ break;
+ case 16:
+ Value = AcpiOsMemIn16 (MemAddress);
+ break;
+ case 32:
+ Value = AcpiOsMemIn32 (MemAddress);
+ break;
+ }
+ break;
+
+
+ case ADDRESS_SPACE_SYSTEM_IO:
+
+ IoAddress = (ACPI_IO_ADDRESS) Reg->Address + Offset;
+
+ switch (Width)
+ {
+ case 8:
+ Value = AcpiOsIn8 (IoAddress);
+ break;
+ case 16:
+ Value = AcpiOsIn16 (IoAddress);
+ break;
+ case 32:
+ Value = AcpiOsIn32 (IoAddress);
+ break;
+ }
+ break;
+
+
+ case ADDRESS_SPACE_PCI_CONFIG:
+
+ PciDevFunc = ACPI_PCI_DEVFUN (Reg->Address);
+ PciRegister = ACPI_PCI_REGISTER (Reg->Address) + Offset;
+
+ switch (Width)
+ {
+ case 8:
+ AcpiOsReadPciCfgByte (0, PciDevFunc, PciRegister, (UINT8 *) &Value);
+ break;
+ case 16:
+ AcpiOsReadPciCfgWord (0, PciDevFunc, PciRegister, (UINT16 *) &Value);
+ break;
+ case 32:
+ AcpiOsReadPciCfgDword (0, PciDevFunc, PciRegister, (UINT32 *) &Value);
+ break;
+ }
+ break;
+ }
+
+ return Value;
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiHwLowLevelWrite
+ *
+ * PARAMETERS: Width - 8, 16, or 32
+ * Value - To be written
+ * Register - GAS register structure
+ * Offset - Offset from the base address in the GAS
+ *
+ *
+ * RETURN: Value read
+ *
+ * DESCRIPTION: Read from either memory, IO, or PCI config space.
+ *
+ ******************************************************************************/
+
+void
+AcpiHwLowLevelWrite (
+ UINT32 Width,
+ UINT32 Value,
+ ACPI_GAS *Reg,
+ UINT32 Offset)
+{
+ ACPI_PHYSICAL_ADDRESS MemAddress;
+ ACPI_IO_ADDRESS IoAddress;
+ UINT32 PciRegister;
+ UINT32 PciDevFunc;
+
+
+ /*
+ * Must have a valid pointer to a GAS structure, and
+ * a non-zero address within
+ */
+ if ((!Reg) ||
+ (!Reg->Address))
+ {
+ return;
+ }
+
+
+ /*
+ * Three address spaces supported:
+ * Memory, Io, or PCI config.
+ */
+
+ switch (Reg->AddressSpaceId)
+ {
+ case ADDRESS_SPACE_SYSTEM_MEMORY:
+
+ MemAddress = (ACPI_PHYSICAL_ADDRESS) Reg->Address + Offset;
+
+ switch (Width)
+ {
+ case 8:
+ AcpiOsMemOut8 (MemAddress, (UINT8) Value);
+ break;
+ case 16:
+ AcpiOsMemOut16 (MemAddress, (UINT16) Value);
+ break;
+ case 32:
+ AcpiOsMemOut32 (MemAddress, (UINT32) Value);
+ break;
+ }
+ break;
+
+
+ case ADDRESS_SPACE_SYSTEM_IO:
+
+ IoAddress = (ACPI_IO_ADDRESS) Reg->Address + Offset;
+
+ switch (Width)
+ {
+ case 8:
+ AcpiOsOut8 (IoAddress, (UINT8) Value);
+ break;
+ case 16:
+ AcpiOsOut16 (IoAddress, (UINT16) Value);
+ break;
+ case 32:
+ AcpiOsOut32 (IoAddress, (UINT32) Value);
+ break;
+ }
+ break;
+
+
+ case ADDRESS_SPACE_PCI_CONFIG:
+
+ PciDevFunc = ACPI_PCI_DEVFUN (Reg->Address);
+ PciRegister = ACPI_PCI_REGISTER (Reg->Address) + Offset;
+
+ switch (Width)
+ {
+ case 8:
+ AcpiOsWritePciCfgByte (0, PciDevFunc, PciRegister, (UINT8) Value);
+ break;
+ case 16:
+ AcpiOsWritePciCfgWord (0, PciDevFunc, PciRegister, (UINT16) Value);
+ break;
+ case 32:
+ AcpiOsWritePciCfgDword (0, PciDevFunc, PciRegister, (UINT32) Value);
+ break;
+ }
+ break;
+ }
+}
+
+
OpenPOWER on IntegriCloud