ReactOS  0.4.14-dev-323-g6fe6a88
hwregs.c File Reference
#include "acpi.h"
#include "accommon.h"
#include "acevents.h"
Include dependency graph for hwregs.c:

Go to the source code of this file.

Macros

#define _COMPONENT   ACPI_HARDWARE
 

Functions

static UINT8 AcpiHwGetAccessBitWidth (UINT64 Address, ACPI_GENERIC_ADDRESS *Reg, UINT8 MaxBitWidth)
 
static ACPI_STATUS AcpiHwReadMultiple (UINT32 *Value, ACPI_GENERIC_ADDRESS *RegisterA, ACPI_GENERIC_ADDRESS *RegisterB)
 
static ACPI_STATUS AcpiHwWriteMultiple (UINT32 Value, ACPI_GENERIC_ADDRESS *RegisterA, ACPI_GENERIC_ADDRESS *RegisterB)
 
ACPI_STATUS AcpiHwValidateRegister (ACPI_GENERIC_ADDRESS *Reg, UINT8 MaxBitWidth, UINT64 *Address)
 
ACPI_STATUS AcpiHwRead (UINT64 *Value, ACPI_GENERIC_ADDRESS *Reg)
 
ACPI_STATUS AcpiHwWrite (UINT64 Value, ACPI_GENERIC_ADDRESS *Reg)
 
ACPI_STATUS AcpiHwClearAcpiStatus (void)
 
ACPI_BIT_REGISTER_INFOAcpiHwGetBitRegisterInfo (UINT32 RegisterId)
 
ACPI_STATUS AcpiHwWritePm1Control (UINT32 Pm1aControl, UINT32 Pm1bControl)
 
ACPI_STATUS AcpiHwRegisterRead (UINT32 RegisterId, UINT32 *ReturnValue)
 
ACPI_STATUS AcpiHwRegisterWrite (UINT32 RegisterId, UINT32 Value)
 

Macro Definition Documentation

◆ _COMPONENT

#define _COMPONENT   ACPI_HARDWARE

Definition at line 49 of file hwregs.c.

Function Documentation

◆ AcpiHwClearAcpiStatus()

ACPI_STATUS AcpiHwClearAcpiStatus ( void  )

Definition at line 452 of file hwregs.c.

454 {
456  ACPI_CPU_FLAGS LockFlags = 0;
457 
458 
459  ACPI_FUNCTION_TRACE (HwClearAcpiStatus);
460 
461 
462  ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n",
464  ACPI_FORMAT_UINT64 (AcpiGbl_XPm1aStatus.Address)));
465 
466  LockFlags = AcpiOsAcquireLock (AcpiGbl_HardwareLock);
467 
468  /* Clear the fixed events in PM1 A/B */
469 
472 
473  AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags);
474 
475  if (ACPI_FAILURE (Status))
476  {
477  goto Exit;
478  }
479 
480  /* Clear the GPE Bits in all GPE registers in all GPE blocks */
481 
483 
484 Exit:
486 }
ACPI_CPU_FLAGS AcpiOsAcquireLock(ACPI_SPINLOCK Handle)
Definition: osl.c:498
ACPI_STATUS AcpiHwClearGpeBlock(ACPI_GPE_XRUPT_INFO *GpeXruptInfo, ACPI_GPE_BLOCK_INFO *GpeBlock, void *Context)
Definition: hwgpe.c:404
#define ACPI_DB_IO
Definition: acoutput.h:177
#define ACPI_CPU_FLAGS
Definition: actypes.h:252
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define ACPI_BITMASK_ALL_FIXED_STATUS
Definition: aclocal.h:1204
smooth NULL
Definition: ftsmooth.c:416
#define ACPI_REGISTER_PM1_STATUS
Definition: aclocal.h:1184
static void Exit(void)
Definition: sock.c:1331
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
Status
Definition: gdiplustypes.h:24
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_FORMAT_UINT64(i)
Definition: acmacros.h:71
ACPI_STATUS AcpiHwRegisterWrite(UINT32 RegisterId, UINT32 Value)
Definition: hwregs.c:684
ACPI_STATUS AcpiEvWalkGpeList(ACPI_GPE_CALLBACK GpeWalkCallback, void *Context)
Definition: evgpeutil.c:67
void AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags)
Definition: osl.c:516

Referenced by AcpiEnterSleepStateS4bios(), and AcpiHwLegacySleep().

◆ AcpiHwGetAccessBitWidth()

static UINT8 AcpiHwGetAccessBitWidth ( UINT64  Address,
ACPI_GENERIC_ADDRESS Reg,
UINT8  MaxBitWidth 
)
static

Definition at line 93 of file hwregs.c.

97 {
98  UINT8 AccessBitWidth;
99 
100 
101  /*
102  * GAS format "register", used by FADT:
103  * 1. Detected if BitOffset is 0 and BitWidth is 8/16/32/64;
104  * 2. AccessSize field is ignored and BitWidth field is used for
105  * determining the boundary of the IO accesses.
106  * GAS format "region", used by APEI registers:
107  * 1. Detected if BitOffset is not 0 or BitWidth is not 8/16/32/64;
108  * 2. AccessSize field is used for determining the boundary of the
109  * IO accesses;
110  * 3. BitOffset/BitWidth fields are used to describe the "region".
111  *
112  * Note: This algorithm assumes that the "Address" fields should always
113  * contain aligned values.
114  */
115  if (!Reg->BitOffset && Reg->BitWidth &&
117  ACPI_IS_ALIGNED (Reg->BitWidth, 8))
118  {
119  AccessBitWidth = Reg->BitWidth;
120  }
121  else if (Reg->AccessWidth)
122  {
123  AccessBitWidth = ACPI_ACCESS_BIT_WIDTH (Reg->AccessWidth);
124  }
125  else
126  {
127  AccessBitWidth = ACPI_ROUND_UP_POWER_OF_TWO_8 (
128  Reg->BitOffset + Reg->BitWidth);
129  if (AccessBitWidth <= 8)
130  {
131  AccessBitWidth = 8;
132  }
133  else
134  {
135  while (!ACPI_IS_ALIGNED (Address, AccessBitWidth >> 3))
136  {
137  AccessBitWidth >>= 1;
138  }
139  }
140  }
141 
142  /* Maximum IO port access bit width is 32 */
143 
144  if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_IO)
145  {
146  MaxBitWidth = 32;
147  }
148 
149  /*
150  * Return access width according to the requested maximum access bit width,
151  * as the caller should know the format of the register and may enforce
152  * a 32-bit accesses.
153  */
154  if (AccessBitWidth < MaxBitWidth)
155  {
156  return (AccessBitWidth);
157  }
158  return (MaxBitWidth);
159 }
#define ACPI_ADR_SPACE_SYSTEM_IO
Definition: actypes.h:852
static WCHAR Address[46]
Definition: ping.c:68
#define ACPI_IS_ALIGNED(a, s)
Definition: acmacros.h:331
#define ACPI_IS_POWER_OF_TWO(a)
Definition: acmacros.h:332
#define ACPI_ACCESS_BIT_WIDTH(size)
Definition: actypes.h:582
unsigned char UINT8
#define ACPI_ROUND_UP_POWER_OF_TWO_8(a)
Definition: acmacros.h:319

Referenced by AcpiHwRead(), AcpiHwValidateRegister(), and AcpiHwWrite().

◆ AcpiHwGetBitRegisterInfo()

ACPI_BIT_REGISTER_INFO* AcpiHwGetBitRegisterInfo ( UINT32  RegisterId)

Definition at line 502 of file hwregs.c.

504 {
506 
507 
508  if (RegisterId > ACPI_BITREG_MAX)
509  {
510  ACPI_ERROR ((AE_INFO, "Invalid BitRegister ID: 0x%X", RegisterId));
511  return (NULL);
512  }
513 
514  return (&AcpiGbl_BitRegisterInfo[RegisterId]);
515 }
smooth NULL
Definition: ftsmooth.c:416
#define AE_INFO
Definition: acoutput.h:230
ACPI_BIT_REGISTER_INFO AcpiGbl_BitRegisterInfo[ACPI_NUM_BITREG]
Definition: utglobal.c:145
#define ACPI_FUNCTION_ENTRY()
Definition: acoutput.h:484
#define ACPI_BITREG_MAX
Definition: actypes.h:922
#define ACPI_ERROR(plist)
Definition: acoutput.h:240

Referenced by AcpiHwLegacySleep(), AcpiHwLegacyWakePrep(), AcpiReadBitRegister(), and AcpiWriteBitRegister().

◆ AcpiHwRead()

ACPI_STATUS AcpiHwRead ( UINT64 Value,
ACPI_GENERIC_ADDRESS Reg 
)

Definition at line 259 of file hwregs.c.

262 {
263  UINT64 Address;
264  UINT8 AccessWidth;
265  UINT32 BitWidth;
266  UINT8 BitOffset;
267  UINT64 Value64;
268  UINT32 Value32;
269  UINT8 Index;
271 
272 
273  ACPI_FUNCTION_NAME (HwRead);
274 
275 
276  /* Validate contents of the GAS register */
277 
278  Status = AcpiHwValidateRegister (Reg, 64, &Address);
279  if (ACPI_FAILURE (Status))
280  {
281  return (Status);
282  }
283 
284  /*
285  * Initialize entire 64-bit return value to zero, convert AccessWidth
286  * into number of bits based
287  */
288  *Value = 0;
289  AccessWidth = AcpiHwGetAccessBitWidth (Address, Reg, 64);
290  BitWidth = Reg->BitOffset + Reg->BitWidth;
291  BitOffset = Reg->BitOffset;
292 
293  /*
294  * Two address spaces supported: Memory or IO. PCI_Config is
295  * not supported here because the GAS structure is insufficient
296  */
297  Index = 0;
298  while (BitWidth)
299  {
300  if (BitOffset >= AccessWidth)
301  {
302  Value64 = 0;
303  BitOffset -= AccessWidth;
304  }
305  else
306  {
308  {
309  Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
310  Address + Index * ACPI_DIV_8 (AccessWidth),
311  &Value64, AccessWidth);
312  }
313  else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
314  {
315  Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
316  Address + Index * ACPI_DIV_8 (AccessWidth),
317  &Value32, AccessWidth);
318  Value64 = (UINT64) Value32;
319  }
320  }
321 
322  /*
323  * Use offset style bit writes because "Index * AccessWidth" is
324  * ensured to be less than 64-bits by AcpiHwValidateRegister().
325  */
326  ACPI_SET_BITS (Value, Index * AccessWidth,
327  ACPI_MASK_BITS_ABOVE_64 (AccessWidth), Value64);
328 
329  BitWidth -= BitWidth > AccessWidth ? AccessWidth : BitWidth;
330  Index++;
331  }
332 
334  "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n",
335  ACPI_FORMAT_UINT64 (*Value), AccessWidth,
337 
338  return (Status);
339 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
ACPI_STATUS AcpiHwValidateRegister(ACPI_GENERIC_ADDRESS *Reg, UINT8 MaxBitWidth, UINT64 *Address)
Definition: hwregs.c:179
#define ACPI_DB_IO
Definition: acoutput.h:177
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_MASK_BITS_ABOVE_64(width)
Definition: acmacros.h:348
ACPI_STATUS AcpiHwReadPort(ACPI_IO_ADDRESS Address, UINT32 *Value, UINT32 Width)
Definition: hwvalid.c:237
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
const char * AcpiUtGetRegionName(UINT8 SpaceId)
Definition: utdecode.c:124
unsigned int UINT32
#define ACPI_SET_BITS(TargetPtr, Position, Mask, Value)
Definition: acmacros.h:371
static WCHAR Address[46]
Definition: ping.c:68
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
static const UCHAR Index[8]
Definition: usbohci.c:18
static UINT8 AcpiHwGetAccessBitWidth(UINT64 Address, ACPI_GENERIC_ADDRESS *Reg, UINT8 MaxBitWidth)
Definition: hwregs.c:93
#define ACPI_DIV_8(a)
Definition: acmacros.h:214
Status
Definition: gdiplustypes.h:24
#define ACPI_FORMAT_UINT64(i)
Definition: acmacros.h:71
ACPI_STATUS AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 *Value, UINT32 Width)
Definition: osl.c:634
#define ACPI_FUNCTION_NAME(a)
Definition: acoutput.h:479
#define ACPI_ADR_SPACE_SYSTEM_MEMORY
Definition: actypes.h:851
unsigned long long UINT64
unsigned char UINT8

Referenced by AcpiEvDetectGpe(), AcpiGetTimer(), AcpiHwGetGpeStatus(), AcpiHwLowSetGpe(), AcpiHwReadMultiple(), AcpiHwRegisterRead(), AcpiHwRegisterWrite(), and AcpiRead().

◆ AcpiHwReadMultiple()

static ACPI_STATUS AcpiHwReadMultiple ( UINT32 Value,
ACPI_GENERIC_ADDRESS RegisterA,
ACPI_GENERIC_ADDRESS RegisterB 
)
static

Definition at line 806 of file hwregs.c.

810 {
811  UINT32 ValueA = 0;
812  UINT32 ValueB = 0;
813  UINT64 Value64;
815 
816 
817  /* The first register is always required */
818 
819  Status = AcpiHwRead (&Value64, RegisterA);
820  if (ACPI_FAILURE (Status))
821  {
822  return (Status);
823  }
824  ValueA = (UINT32) Value64;
825 
826  /* Second register is optional */
827 
828  if (RegisterB->Address)
829  {
830  Status = AcpiHwRead (&Value64, RegisterB);
831  if (ACPI_FAILURE (Status))
832  {
833  return (Status);
834  }
835  ValueB = (UINT32) Value64;
836  }
837 
838  /*
839  * OR the two return values together. No shifting or masking is necessary,
840  * because of how the PM1 registers are defined in the ACPI specification:
841  *
842  * "Although the bits can be split between the two register blocks (each
843  * register block has a unique pointer within the FADT), the bit positions
844  * are maintained. The register block with unimplemented bits (that is,
845  * those implemented in the other register block) always returns zeros,
846  * and writes have no side effects"
847  */
848  *Value = (ValueA | ValueB);
849  return (AE_OK);
850 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
unsigned int UINT32
ACPI_STATUS AcpiHwRead(UINT64 *Value, ACPI_GENERIC_ADDRESS *Reg)
Definition: hwregs.c:259
Status
Definition: gdiplustypes.h:24
unsigned long long UINT64
#define AE_OK
Definition: acexcep.h:97

Referenced by AcpiHwRegisterRead(), and AcpiHwRegisterWrite().

◆ AcpiHwRegisterRead()

ACPI_STATUS AcpiHwRegisterRead ( UINT32  RegisterId,
UINT32 ReturnValue 
)

Definition at line 574 of file hwregs.c.

577 {
578  UINT32 Value = 0;
579  UINT64 Value64;
581 
582 
583  ACPI_FUNCTION_TRACE (HwRegisterRead);
584 
585 
586  switch (RegisterId)
587  {
588  case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */
589 
591  &AcpiGbl_XPm1aStatus,
592  &AcpiGbl_XPm1bStatus);
593  break;
594 
595  case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */
596 
598  &AcpiGbl_XPm1aEnable,
599  &AcpiGbl_XPm1bEnable);
600  break;
601 
602  case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
603 
605  &AcpiGbl_FADT.XPm1aControlBlock,
606  &AcpiGbl_FADT.XPm1bControlBlock);
607 
608  /*
609  * Zero the write-only bits. From the ACPI specification, "Hardware
610  * Write-Only Bits": "Upon reads to registers with write-only bits,
611  * software masks out all write-only bits."
612  */
614  break;
615 
616  case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
617 
618  Status = AcpiHwRead (&Value64, &AcpiGbl_FADT.XPm2ControlBlock);
619  if (ACPI_SUCCESS (Status))
620  {
621  Value = (UINT32) Value64;
622  }
623  break;
624 
625  case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
626 
627  Status = AcpiHwRead (&Value64, &AcpiGbl_FADT.XPmTimerBlock);
628  if (ACPI_SUCCESS (Status))
629  {
630  Value = (UINT32) Value64;
631  }
632 
633  break;
634 
635  case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
636 
637  Status = AcpiHwReadPort (AcpiGbl_FADT.SmiCommand, &Value, 8);
638  break;
639 
640  default:
641 
642  ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
643  RegisterId));
645  break;
646  }
647 
648  if (ACPI_SUCCESS (Status))
649  {
650  *ReturnValue = (UINT32) Value;
651  }
652 
654 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
#define ACPI_REGISTER_PM2_CONTROL
Definition: aclocal.h:1187
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
#define ACPI_REGISTER_PM1_CONTROL
Definition: aclocal.h:1186
UINT32 ACPI_STATUS
Definition: actypes.h:460
ACPI_STATUS AcpiHwReadPort(ACPI_IO_ADDRESS Address, UINT32 *Value, UINT32 Width)
Definition: hwvalid.c:237
UINT32 void void ** ReturnValue
Definition: acevents.h:214
unsigned int UINT32
#define AE_INFO
Definition: acoutput.h:230
#define ACPI_REGISTER_PM_TIMER
Definition: aclocal.h:1188
#define ACPI_REGISTER_PM1_STATUS
Definition: aclocal.h:1184
#define ACPI_PM1_CONTROL_WRITEONLY_BITS
Definition: aclocal.h:1161
ACPI_STATUS AcpiHwRead(UINT64 *Value, ACPI_GENERIC_ADDRESS *Reg)
Definition: hwregs.c:259
static ACPI_STATUS AcpiHwReadMultiple(UINT32 *Value, ACPI_GENERIC_ADDRESS *RegisterA, ACPI_GENERIC_ADDRESS *RegisterB)
Definition: hwregs.c:806
Status
Definition: gdiplustypes.h:24
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_REGISTER_SMI_COMMAND_BLOCK
Definition: aclocal.h:1190
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
unsigned long long UINT64
#define ACPI_REGISTER_PM1_ENABLE
Definition: aclocal.h:1185

Referenced by AcpiEvFixedEventDetect(), AcpiHwLegacySleep(), AcpiHwLegacyWakePrep(), AcpiReadBitRegister(), and AcpiWriteBitRegister().

◆ AcpiHwRegisterWrite()

ACPI_STATUS AcpiHwRegisterWrite ( UINT32  RegisterId,
UINT32  Value 
)

Definition at line 684 of file hwregs.c.

687 {
689  UINT32 ReadValue;
690  UINT64 ReadValue64;
691 
692 
693  ACPI_FUNCTION_TRACE (HwRegisterWrite);
694 
695 
696  switch (RegisterId)
697  {
698  case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */
699  /*
700  * Handle the "ignored" bit in PM1 Status. According to the ACPI
701  * specification, ignored bits are to be preserved when writing.
702  * Normally, this would mean a read/modify/write sequence. However,
703  * preserving a bit in the status register is different. Writing a
704  * one clears the status, and writing a zero preserves the status.
705  * Therefore, we must always write zero to the ignored bit.
706  *
707  * This behavior is clarified in the ACPI 4.0 specification.
708  */
710 
712  &AcpiGbl_XPm1aStatus,
713  &AcpiGbl_XPm1bStatus);
714  break;
715 
716  case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */
717 
719  &AcpiGbl_XPm1aEnable,
720  &AcpiGbl_XPm1bEnable);
721  break;
722 
723  case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
724  /*
725  * Perform a read first to preserve certain bits (per ACPI spec)
726  * Note: This includes SCI_EN, we never want to change this bit
727  */
728  Status = AcpiHwReadMultiple (&ReadValue,
729  &AcpiGbl_FADT.XPm1aControlBlock,
730  &AcpiGbl_FADT.XPm1bControlBlock);
731  if (ACPI_FAILURE (Status))
732  {
733  goto Exit;
734  }
735 
736  /* Insert the bits to be preserved */
737 
739 
740  /* Now we can write the data */
741 
743  &AcpiGbl_FADT.XPm1aControlBlock,
744  &AcpiGbl_FADT.XPm1bControlBlock);
745  break;
746 
747  case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
748  /*
749  * For control registers, all reserved bits must be preserved,
750  * as per the ACPI spec.
751  */
752  Status = AcpiHwRead (&ReadValue64, &AcpiGbl_FADT.XPm2ControlBlock);
753  if (ACPI_FAILURE (Status))
754  {
755  goto Exit;
756  }
757  ReadValue = (UINT32) ReadValue64;
758 
759  /* Insert the bits to be preserved */
760 
762 
763  Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPm2ControlBlock);
764  break;
765 
766  case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
767 
768  Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPmTimerBlock);
769  break;
770 
771  case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
772 
773  /* SMI_CMD is currently always in IO space */
774 
775  Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand, Value, 8);
776  break;
777 
778  default:
779 
780  ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
781  RegisterId));
783  break;
784  }
785 
786 Exit:
788 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define ACPI_REGISTER_PM2_CONTROL
Definition: aclocal.h:1187
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
#define ACPI_REGISTER_PM1_CONTROL
Definition: aclocal.h:1186
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define ACPI_PM1_STATUS_PRESERVED_BITS
Definition: aclocal.h:1157
unsigned int UINT32
#define ACPI_INSERT_BITS(Target, Mask, Source)
Definition: acmacros.h:363
ACPI_STATUS AcpiHwWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width)
Definition: hwvalid.c:312
static ACPI_STATUS AcpiHwWriteMultiple(UINT32 Value, ACPI_GENERIC_ADDRESS *RegisterA, ACPI_GENERIC_ADDRESS *RegisterB)
Definition: hwregs.c:868
#define AE_INFO
Definition: acoutput.h:230
#define ACPI_REGISTER_PM_TIMER
Definition: aclocal.h:1188
#define ACPI_REGISTER_PM1_STATUS
Definition: aclocal.h:1184
static void Exit(void)
Definition: sock.c:1331
ACPI_STATUS AcpiHwRead(UINT64 *Value, ACPI_GENERIC_ADDRESS *Reg)
Definition: hwregs.c:259
static ACPI_STATUS AcpiHwReadMultiple(UINT32 *Value, ACPI_GENERIC_ADDRESS *RegisterA, ACPI_GENERIC_ADDRESS *RegisterB)
Definition: hwregs.c:806
Status
Definition: gdiplustypes.h:24
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_REGISTER_SMI_COMMAND_BLOCK
Definition: aclocal.h:1190
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
unsigned long long UINT64
#define ACPI_PM1_CONTROL_PRESERVED_BITS
Definition: aclocal.h:1175
#define ACPI_PM2_CONTROL_PRESERVED_BITS
Definition: aclocal.h:1178
#define ACPI_REGISTER_PM1_ENABLE
Definition: aclocal.h:1185
ACPI_STATUS AcpiHwWrite(UINT64 Value, ACPI_GENERIC_ADDRESS *Reg)
Definition: hwregs.c:357

Referenced by AcpiHwClearAcpiStatus(), AcpiHwLegacySleep(), and AcpiWriteBitRegister().

◆ AcpiHwValidateRegister()

ACPI_STATUS AcpiHwValidateRegister ( ACPI_GENERIC_ADDRESS Reg,
UINT8  MaxBitWidth,
UINT64 Address 
)

Definition at line 179 of file hwregs.c.

183 {
184  UINT8 BitWidth;
185  UINT8 AccessWidth;
186 
187 
188  /* Must have a valid pointer to a GAS structure */
189 
190  if (!Reg)
191  {
192  return (AE_BAD_PARAMETER);
193  }
194 
195  /*
196  * Copy the target address. This handles possible alignment issues.
197  * Address must not be null. A null address also indicates an optional
198  * ACPI register that is not supported, so no error message.
199  */
201  if (!(*Address))
202  {
203  return (AE_BAD_ADDRESS);
204  }
205 
206  /* Validate the SpaceID */
207 
208  if ((Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
210  {
212  "Unsupported address space: 0x%X", Reg->SpaceId));
213  return (AE_SUPPORT);
214  }
215 
216  /* Validate the AccessWidth */
217 
218  if (Reg->AccessWidth > 4)
219  {
221  "Unsupported register access width: 0x%X", Reg->AccessWidth));
222  return (AE_SUPPORT);
223  }
224 
225  /* Validate the BitWidth, convert AccessWidth into number of bits */
226 
227  AccessWidth = AcpiHwGetAccessBitWidth (*Address, Reg, MaxBitWidth);
228  BitWidth = ACPI_ROUND_UP (Reg->BitOffset + Reg->BitWidth, AccessWidth);
229  if (MaxBitWidth < BitWidth)
230  {
232  "Requested bit width 0x%X is smaller than register bit width 0x%X",
233  MaxBitWidth, BitWidth));
234  return (AE_SUPPORT);
235  }
236 
237  return (AE_OK);
238 }
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
#define ACPI_WARNING(plist)
Definition: acoutput.h:238
#define ACPI_ADR_SPACE_SYSTEM_IO
Definition: actypes.h:852
#define AE_INFO
Definition: acoutput.h:230
static WCHAR Address[46]
Definition: ping.c:68
#define AE_BAD_ADDRESS
Definition: acexcep.h:159
#define ACPI_ROUND_UP(value, boundary)
Definition: acmacros.h:242
#define AE_SUPPORT
Definition: acexcep.h:123
static UINT8 AcpiHwGetAccessBitWidth(UINT64 Address, ACPI_GENERIC_ADDRESS *Reg, UINT8 MaxBitWidth)
Definition: hwregs.c:93
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define ACPI_MOVE_64_TO_64(d, s)
Definition: acmacros.h:155
#define ACPI_ADR_SPACE_SYSTEM_MEMORY
Definition: actypes.h:851
unsigned char UINT8
#define AE_OK
Definition: acexcep.h:97

Referenced by AcpiHwRead(), and AcpiHwWrite().

◆ AcpiHwWrite()

ACPI_STATUS AcpiHwWrite ( UINT64  Value,
ACPI_GENERIC_ADDRESS Reg 
)

Definition at line 357 of file hwregs.c.

360 {
361  UINT64 Address;
362  UINT8 AccessWidth;
363  UINT32 BitWidth;
364  UINT8 BitOffset;
365  UINT64 Value64;
366  UINT8 Index;
368 
369 
370  ACPI_FUNCTION_NAME (HwWrite);
371 
372 
373  /* Validate contents of the GAS register */
374 
375  Status = AcpiHwValidateRegister (Reg, 64, &Address);
376  if (ACPI_FAILURE (Status))
377  {
378  return (Status);
379  }
380 
381  /* Convert AccessWidth into number of bits based */
382 
383  AccessWidth = AcpiHwGetAccessBitWidth (Address, Reg, 64);
384  BitWidth = Reg->BitOffset + Reg->BitWidth;
385  BitOffset = Reg->BitOffset;
386 
387  /*
388  * Two address spaces supported: Memory or IO. PCI_Config is
389  * not supported here because the GAS structure is insufficient
390  */
391  Index = 0;
392  while (BitWidth)
393  {
394  /*
395  * Use offset style bit reads because "Index * AccessWidth" is
396  * ensured to be less than 64-bits by AcpiHwValidateRegister().
397  */
398  Value64 = ACPI_GET_BITS (&Value, Index * AccessWidth,
399  ACPI_MASK_BITS_ABOVE_64 (AccessWidth));
400 
401  if (BitOffset >= AccessWidth)
402  {
403  BitOffset -= AccessWidth;
404  }
405  else
406  {
408  {
409  Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
410  Address + Index * ACPI_DIV_8 (AccessWidth),
411  Value64, AccessWidth);
412  }
413  else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
414  {
415  Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
416  Address + Index * ACPI_DIV_8 (AccessWidth),
417  (UINT32) Value64, AccessWidth);
418  }
419  }
420 
421  /*
422  * Index * AccessWidth is ensured to be less than 32-bits by
423  * AcpiHwValidateRegister().
424  */
425  BitWidth -= BitWidth > AccessWidth ? AccessWidth : BitWidth;
426  Index++;
427  }
428 
430  "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n",
431  ACPI_FORMAT_UINT64 (Value), AccessWidth,
433 
434  return (Status);
435 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
ACPI_STATUS AcpiHwValidateRegister(ACPI_GENERIC_ADDRESS *Reg, UINT8 MaxBitWidth, UINT64 *Address)
Definition: hwregs.c:179
#define ACPI_DB_IO
Definition: acoutput.h:177
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_MASK_BITS_ABOVE_64(width)
Definition: acmacros.h:348
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
const char * AcpiUtGetRegionName(UINT8 SpaceId)
Definition: utdecode.c:124
unsigned int UINT32
ACPI_STATUS AcpiHwWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width)
Definition: hwvalid.c:312
static WCHAR Address[46]
Definition: ping.c:68
ACPI_STATUS AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 Value, UINT32 Width)
Definition: osl.c:667
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
static const UCHAR Index[8]
Definition: usbohci.c:18
static UINT8 AcpiHwGetAccessBitWidth(UINT64 Address, ACPI_GENERIC_ADDRESS *Reg, UINT8 MaxBitWidth)
Definition: hwregs.c:93
#define ACPI_DIV_8(a)
Definition: acmacros.h:214
Status
Definition: gdiplustypes.h:24
#define ACPI_FORMAT_UINT64(i)
Definition: acmacros.h:71
#define ACPI_FUNCTION_NAME(a)
Definition: acoutput.h:479
#define ACPI_ADR_SPACE_SYSTEM_MEMORY
Definition: actypes.h:851
unsigned long long UINT64
#define ACPI_GET_BITS(SourcePtr, Position, Mask)
Definition: acmacros.h:368
unsigned char UINT8

Referenced by AcpiEvCreateGpeInfoBlocks(), AcpiHwClearGpe(), AcpiHwClearGpeBlock(), AcpiHwGpeEnableWrite(), AcpiHwLowSetGpe(), AcpiHwRegisterWrite(), AcpiHwWriteMultiple(), AcpiHwWritePm1Control(), AcpiReset(), and AcpiWrite().

◆ AcpiHwWriteMultiple()

static ACPI_STATUS AcpiHwWriteMultiple ( UINT32  Value,
ACPI_GENERIC_ADDRESS RegisterA,
ACPI_GENERIC_ADDRESS RegisterB 
)
static

Definition at line 868 of file hwregs.c.

872 {
874 
875 
876  /* The first register is always required */
877 
878  Status = AcpiHwWrite (Value, RegisterA);
879  if (ACPI_FAILURE (Status))
880  {
881  return (Status);
882  }
883 
884  /*
885  * Second register is optional
886  *
887  * No bit shifting or clearing is necessary, because of how the PM1
888  * registers are defined in the ACPI specification:
889  *
890  * "Although the bits can be split between the two register blocks (each
891  * register block has a unique pointer within the FADT), the bit positions
892  * are maintained. The register block with unimplemented bits (that is,
893  * those implemented in the other register block) always returns zeros,
894  * and writes have no side effects"
895  */
896  if (RegisterB->Address)
897  {
898  Status = AcpiHwWrite (Value, RegisterB);
899  }
900 
901  return (Status);
902 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
Status
Definition: gdiplustypes.h:24
ACPI_STATUS AcpiHwWrite(UINT64 Value, ACPI_GENERIC_ADDRESS *Reg)
Definition: hwregs.c:357

Referenced by AcpiHwRegisterWrite().

◆ AcpiHwWritePm1Control()

ACPI_STATUS AcpiHwWritePm1Control ( UINT32  Pm1aControl,
UINT32  Pm1bControl 
)

Definition at line 536 of file hwregs.c.

539 {
541 
542 
543  ACPI_FUNCTION_TRACE (HwWritePm1Control);
544 
545 
546  Status = AcpiHwWrite (Pm1aControl, &AcpiGbl_FADT.XPm1aControlBlock);
547  if (ACPI_FAILURE (Status))
548  {
550  }
551 
552  if (AcpiGbl_FADT.XPm1bControlBlock.Address)
553  {
554  Status = AcpiHwWrite (Pm1bControl, &AcpiGbl_FADT.XPm1bControlBlock);
555  }
557 }
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
Status
Definition: gdiplustypes.h:24
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
ACPI_STATUS AcpiHwWrite(UINT64 Value, ACPI_GENERIC_ADDRESS *Reg)
Definition: hwregs.c:357

Referenced by AcpiHwLegacySleep(), and AcpiHwLegacyWakePrep().