ACPI_STATUS AcpiHwRead ( UINT32 *Value, ACPI_GENERIC_ADDRESS *Reg) { UINT64 Address; UINT64 Value64; ACPI_STATUS Status; ACPI_FUNCTION_NAME (HwRead); /* Validate contents of the GAS register */ Status = AcpiHwValidateRegister (Reg, 32, &Address); if (ACPI_FAILURE (Status)) { return (Status); } /* Initialize entire 32-bit return value to zero */ *Value = 0; /* * Two address spaces supported: Memory or IO. PCI_Config is * not supported here because the GAS structure is insufficient */ if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) { Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS) Address, &Value64, Reg->BitWidth); *Value = (UINT32) Value64; } else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ { Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) Address, Value, Reg->BitWidth); } ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", *Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address), AcpiUtGetRegionName (Reg->SpaceId))); return (Status); }
static ACPI_STATUS acpi_wdrt_read_count(struct acpi_wdrt_softc *sc, uint32_t *val) { ACPI_STATUS rv; KASSERT(sc->sc_smw_valid == true); rv = AcpiOsReadMemory(sc->sc_count_reg.Address, val, sc->sc_count_reg.BitWidth); DPRINTF(("%s: %s 0x%" PRIx64 "/%u 0x%08x (%u)\n", device_xname(sc->sc_dev), __func__, sc->sc_count_reg.Address, sc->sc_count_reg.BitWidth, *val, rv)); return rv; }
static int acpi_wdrt_match(device_t parent, cfdata_t match, void *opaque) { ACPI_TABLE_WDRT *wdrt; ACPI_STATUS rv; uint32_t val; rv = AcpiGetTable(ACPI_SIG_WDRT, 1, (ACPI_TABLE_HEADER **)&wdrt); if (ACPI_FAILURE(rv)) return 0; /* Only system memory address spaces are allowed */ if (wdrt->ControlRegister.SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY || wdrt->CountRegister.SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) { return 0; } /* Sanity check control & count register addresses */ if (wdrt->ControlRegister.Address == 0 || wdrt->ControlRegister.Address == 0xffffffff || wdrt->ControlRegister.Address == 0xffffffffffffffff || wdrt->CountRegister.Address == 0 || wdrt->CountRegister.Address == 0xffffffff || wdrt->CountRegister.Address == 0xffffffffffffffff) { return 0; } /* Read control regster */ rv = AcpiOsReadMemory(wdrt->ControlRegister.Address, &val, wdrt->ControlRegister.BitWidth); if (ACPI_FAILURE(rv)) return 0; /* Make sure the hardware watchdog is enabled */ if ((val & ACPI_WDRT_CSR_WDOGEN) == ACPI_WDRT_WDOGEN_DISABLE) return 0; return 1; }
ACPI_STATUS AcpiHwWrite ( UINT32 Value, ACPI_GENERIC_ADDRESS *Reg) { UINT64 Address; UINT8 AccessWidth; UINT32 BitWidth; UINT8 BitOffset; UINT64 Value64; UINT32 NewValue32, OldValue32; UINT8 Index; ACPI_STATUS Status; ACPI_FUNCTION_NAME (HwWrite); /* Validate contents of the GAS register */ Status = AcpiHwValidateRegister (Reg, 32, &Address); if (ACPI_FAILURE (Status)) { return (Status); } /* Convert AccessWidth into number of bits based */ AccessWidth = Reg->AccessWidth ? Reg->AccessWidth : 1; AccessWidth = 1 << (AccessWidth + 2); BitWidth = ACPI_ROUND_UP (Reg->BitOffset + Reg->BitWidth, AccessWidth); BitOffset = Reg->BitOffset; /* * Two address spaces supported: Memory or IO. PCI_Config is * not supported here because the GAS structure is insufficient */ Index = 0; while (BitWidth) { NewValue32 = ACPI_GET_BITS (&Value, (Index * AccessWidth), ((1 << AccessWidth) - 1)); if (BitOffset > AccessWidth) { BitOffset -= AccessWidth; } else { if (BitOffset) { NewValue32 &= ACPI_MASK_BITS_BELOW (BitOffset); } if (BitWidth < AccessWidth) { NewValue32 &= ACPI_MASK_BITS_ABOVE (BitWidth); } if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) { if (BitOffset || BitWidth < AccessWidth) { /* * Read old values in order not to modify the bits that * are beyond the register BitWidth/BitOffset setting. */ Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS) Address + Index * ACPI_DIV_8 (AccessWidth), &Value64, AccessWidth); OldValue32 = (UINT32) Value64; if (BitOffset) { OldValue32 &= ACPI_MASK_BITS_ABOVE (BitOffset + 1); BitOffset = 0; } if (BitWidth < AccessWidth) { OldValue32 &= ACPI_MASK_BITS_BELOW (BitWidth - 1); } NewValue32 |= OldValue32; } Value64 = (UINT64) NewValue32; Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS) Address + Index * ACPI_DIV_8 (AccessWidth), Value64, AccessWidth); } else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ { if (BitOffset || BitWidth < AccessWidth) { /* * Read old values in order not to modify the bits that * are beyond the register BitWidth/BitOffset setting. */ Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) Address + Index * ACPI_DIV_8 (AccessWidth), &OldValue32, AccessWidth); if (BitOffset) { OldValue32 &= ACPI_MASK_BITS_ABOVE (BitOffset + 1); BitOffset = 0; } if (BitWidth < AccessWidth) { OldValue32 &= ACPI_MASK_BITS_BELOW (BitWidth - 1); } NewValue32 |= OldValue32; } Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) Address + Index * ACPI_DIV_8 (AccessWidth), NewValue32, AccessWidth); } } BitWidth -= BitWidth > AccessWidth ? AccessWidth : BitWidth; Index++; } ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", Value, AccessWidth, ACPI_FORMAT_UINT64 (Address), AcpiUtGetRegionName (Reg->SpaceId))); return (Status); }
ACPI_STATUS AcpiHwRead ( UINT32 *Value, ACPI_GENERIC_ADDRESS *Reg) { UINT64 Address; UINT8 AccessWidth; UINT32 BitWidth; UINT8 BitOffset; UINT64 Value64; UINT32 Value32; UINT8 Index; ACPI_STATUS Status; ACPI_FUNCTION_NAME (HwRead); /* Validate contents of the GAS register */ Status = AcpiHwValidateRegister (Reg, 32, &Address); if (ACPI_FAILURE (Status)) { return (Status); } /* * Initialize entire 32-bit return value to zero, convert AccessWidth * into number of bits based */ *Value = 0; AccessWidth = Reg->AccessWidth ? Reg->AccessWidth : 1; AccessWidth = 1 << (AccessWidth + 2); BitWidth = ACPI_ROUND_UP (Reg->BitOffset + Reg->BitWidth, AccessWidth); BitOffset = Reg->BitOffset; /* * Two address spaces supported: Memory or IO. PCI_Config is * not supported here because the GAS structure is insufficient */ Index = 0; while (BitWidth) { if (BitOffset > AccessWidth) { Value32 = 0; BitOffset -= AccessWidth; } else { if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) { Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS) Address + Index * ACPI_DIV_8 (AccessWidth), &Value64, AccessWidth); Value32 = (UINT32) Value64; } else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ { Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) Address + Index * ACPI_DIV_8 (AccessWidth), &Value32, AccessWidth); } if (BitOffset) { Value32 &= ACPI_MASK_BITS_BELOW (BitOffset); BitOffset = 0; } if (BitWidth < AccessWidth) { Value32 &= ACPI_MASK_BITS_ABOVE (BitWidth); } } ACPI_SET_BITS (Value, Index * AccessWidth, ((1 << AccessWidth) - 1), Value32); BitWidth -= BitWidth > AccessWidth ? AccessWidth : BitWidth; Index++; } ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", *Value, AccessWidth, ACPI_FORMAT_UINT64 (Address), AcpiUtGetRegionName (Reg->SpaceId))); return (Status); }
ACPI_STATUS AcpiHwRead ( UINT64 *Value, ACPI_GENERIC_ADDRESS *Reg) { UINT64 Address; UINT8 AccessWidth; UINT32 BitWidth; UINT8 BitOffset; UINT64 Value64; UINT32 Value32; UINT8 Index; ACPI_STATUS Status; ACPI_FUNCTION_NAME (HwRead); /* Validate contents of the GAS register */ Status = AcpiHwValidateRegister (Reg, 64, &Address); if (ACPI_FAILURE (Status)) { return (Status); } /* * Initialize entire 64-bit return value to zero, convert AccessWidth * into number of bits based */ *Value = 0; AccessWidth = AcpiHwGetAccessBitWidth (Address, Reg, 64); BitWidth = Reg->BitOffset + Reg->BitWidth; BitOffset = Reg->BitOffset; /* * Two address spaces supported: Memory or IO. PCI_Config is * not supported here because the GAS structure is insufficient */ Index = 0; while (BitWidth) { if (BitOffset >= AccessWidth) { Value64 = 0; BitOffset -= AccessWidth; } else { if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) { Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS) Address + Index * ACPI_DIV_8 (AccessWidth), &Value64, AccessWidth); } else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ { Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) Address + Index * ACPI_DIV_8 (AccessWidth), &Value32, AccessWidth); Value64 = (UINT64) Value32; } } /* * Use offset style bit writes because "Index * AccessWidth" is * ensured to be less than 64-bits by AcpiHwValidateRegister(). */ ACPI_SET_BITS (Value, Index * AccessWidth, ACPI_MASK_BITS_ABOVE_64 (AccessWidth), Value64); BitWidth -= BitWidth > AccessWidth ? AccessWidth : BitWidth; Index++; } ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n", ACPI_FORMAT_UINT64 (*Value), AccessWidth, ACPI_FORMAT_UINT64 (Address), AcpiUtGetRegionName (Reg->SpaceId))); return (Status); }