diff options
Diffstat (limited to 'sys/contrib/dev/acpica/hwregs.c')
-rw-r--r-- | sys/contrib/dev/acpica/hwregs.c | 952 |
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; + } +} + + |