ReactOS 0.4.16-dev-295-g4aee028
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
484Exit:
486}
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define ACPI_BITMASK_ALL_FIXED_STATUS
Definition: aclocal.h:1204
#define ACPI_REGISTER_PM1_STATUS
Definition: aclocal.h:1184
#define ACPI_FORMAT_UINT64(i)
Definition: acmacros.h:71
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_DB_IO
Definition: acoutput.h:177
void AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags)
Definition: osl.c:516
ACPI_CPU_FLAGS AcpiOsAcquireLock(ACPI_SPINLOCK Handle)
Definition: osl.c:498
#define ACPI_CPU_FLAGS
Definition: actypes.h:252
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define NULL
Definition: types.h:112
ACPI_STATUS AcpiEvWalkGpeList(ACPI_GPE_CALLBACK GpeWalkCallback, void *Context)
Definition: evgpeutil.c:67
Status
Definition: gdiplustypes.h:25
ACPI_STATUS AcpiHwClearGpeBlock(ACPI_GPE_XRUPT_INFO *GpeXruptInfo, ACPI_GPE_BLOCK_INFO *GpeBlock, void *Context)
Definition: hwgpe.c:404
ACPI_STATUS AcpiHwRegisterWrite(UINT32 RegisterId, UINT32 Value)
Definition: hwregs.c:684
static void Exit(void)
Definition: sock.c:1330

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
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}
unsigned char UINT8
#define ACPI_IS_ALIGNED(a, s)
Definition: acmacros.h:331
#define ACPI_ROUND_UP_POWER_OF_TWO_8(a)
Definition: acmacros.h:319
#define ACPI_IS_POWER_OF_TWO(a)
Definition: acmacros.h:332
#define ACPI_ADR_SPACE_SYSTEM_IO
Definition: actypes.h:862
#define ACPI_ACCESS_BIT_WIDTH(size)
Definition: actypes.h:591
static WCHAR Address[46]
Definition: ping.c:68

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}
ACPI_BIT_REGISTER_INFO AcpiGbl_BitRegisterInfo[ACPI_NUM_BITREG]
Definition: utglobal.c:145
#define ACPI_FUNCTION_ENTRY()
Definition: acoutput.h:484
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define AE_INFO
Definition: acoutput.h:230
#define ACPI_BITREG_MAX
Definition: actypes.h:933

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{
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
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}
unsigned long long UINT64
unsigned int UINT32
#define ACPI_SET_BITS(TargetPtr, Position, Mask, Value)
Definition: acmacros.h:371
#define ACPI_DIV_8(a)
Definition: acmacros.h:214
#define ACPI_MASK_BITS_ABOVE_64(width)
Definition: acmacros.h:348
#define ACPI_FUNCTION_NAME(a)
Definition: acoutput.h:479
ACPI_STATUS AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 *Value, UINT32 Width)
Definition: osl.c:634
#define ACPI_ADR_SPACE_SYSTEM_MEMORY
Definition: actypes.h:861
const char * AcpiUtGetRegionName(UINT8 SpaceId)
Definition: utdecode.c:125
ACPI_STATUS AcpiHwValidateRegister(ACPI_GENERIC_ADDRESS *Reg, UINT8 MaxBitWidth, UINT64 *Address)
Definition: hwregs.c:179
static UINT8 AcpiHwGetAccessBitWidth(UINT64 Address, ACPI_GENERIC_ADDRESS *Reg, UINT8 MaxBitWidth)
Definition: hwregs.c:93
ACPI_STATUS AcpiHwReadPort(ACPI_IO_ADDRESS Address, UINT32 *Value, UINT32 Width)
Definition: hwvalid.c:237
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by AcpiEvDetectGpe(), AcpiGetTimer(), AcpiHwGetGpeBlockStatus(), 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}
#define AE_OK
Definition: acexcep.h:97
ACPI_STATUS AcpiHwRead(UINT64 *Value, ACPI_GENERIC_ADDRESS *Reg)
Definition: hwregs.c:259

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 */
613 Value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS;
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 {
651 }
652
654}
UINT32 void void ** ReturnValue
Definition: acevents.h:216
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
#define ACPI_REGISTER_PM2_CONTROL
Definition: aclocal.h:1187
#define ACPI_REGISTER_PM1_ENABLE
Definition: aclocal.h:1185
#define ACPI_REGISTER_PM_TIMER
Definition: aclocal.h:1188
#define ACPI_REGISTER_SMI_COMMAND_BLOCK
Definition: aclocal.h:1190
#define ACPI_REGISTER_PM1_CONTROL
Definition: aclocal.h:1186
static ACPI_STATUS AcpiHwReadMultiple(UINT32 *Value, ACPI_GENERIC_ADDRESS *RegisterA, ACPI_GENERIC_ADDRESS *RegisterB)
Definition: hwregs.c:806

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 */
709 Value &= ~ACPI_PM1_STATUS_PRESERVED_BITS;
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
786Exit:
788}
#define ACPI_PM1_CONTROL_PRESERVED_BITS
Definition: aclocal.h:1175
#define ACPI_PM2_CONTROL_PRESERVED_BITS
Definition: aclocal.h:1178
#define ACPI_INSERT_BITS(Target, Mask, Source)
Definition: acmacros.h:363
ACPI_STATUS AcpiHwWrite(UINT64 Value, ACPI_GENERIC_ADDRESS *Reg)
Definition: hwregs.c:357
static ACPI_STATUS AcpiHwWriteMultiple(UINT32 Value, ACPI_GENERIC_ADDRESS *RegisterA, ACPI_GENERIC_ADDRESS *RegisterB)
Definition: hwregs.c:868
ACPI_STATUS AcpiHwWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width)
Definition: hwvalid.c:312

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
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_SUPPORT
Definition: acexcep.h:123
#define AE_BAD_ADDRESS
Definition: acexcep.h:159
#define ACPI_MOVE_64_TO_64(d, s)
Definition: acmacros.h:155
#define ACPI_ROUND_UP(value, boundary)
Definition: acmacros.h:242
#define ACPI_WARNING(plist)
Definition: acoutput.h:238

Referenced by AcpiHwRead(), and AcpiHwWrite().

◆ AcpiHwWrite()

ACPI_STATUS AcpiHwWrite ( UINT64  Value,
ACPI_GENERIC_ADDRESS Reg 
)

Definition at line 357 of file hwregs.c.

360{
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
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}
#define ACPI_GET_BITS(SourcePtr, Position, Mask)
Definition: acmacros.h:368
ACPI_STATUS AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 Value, UINT32 Width)
Definition: osl.c:667

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}

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}

Referenced by AcpiHwLegacySleep(), and AcpiHwLegacyWakePrep().