static ACPI_STATUS
acpi_wdrt_write_count(struct acpi_wdrt_softc *sc, uint32_t val)
{
	ACPI_STATUS rv;

	KASSERT(sc->sc_smw_valid == true);

	rv = AcpiOsWriteMemory(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;
}
ACPI_STATUS
AcpiHwWrite (
    UINT32                  Value,
    ACPI_GENERIC_ADDRESS    *Reg)
{
    UINT64                  Address;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_NAME (HwWrite);


    /* Validate contents of the GAS register */

    Status = AcpiHwValidateRegister (Reg, 32, &Address);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    /*
     * 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 = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
                    Address, (UINT64) Value, Reg->BitWidth);
    }
    else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
    {
        Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
                    Address, Value, Reg->BitWidth);
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_IO,
        "Wrote: %8.8X width %2d   to %8.8X%8.8X (%s)\n",
        Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address),
        AcpiUtGetRegionName (Reg->SpaceId)));

    return (Status);
}
Beispiel #3
0
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);
}
Beispiel #4
0
ACPI_STATUS
AcpiHwWrite (
    UINT64                  Value,
    ACPI_GENERIC_ADDRESS    *Reg)
{
    UINT64                  Address;
    UINT8                   AccessWidth;
    UINT32                  BitWidth;
    UINT8                   BitOffset;
    UINT64                  Value64;
    UINT8                   Index;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_NAME (HwWrite);


    /* Validate contents of the GAS register */

    Status = AcpiHwValidateRegister (Reg, 64, &Address);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    /* Convert AccessWidth into number of bits based */

    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)
    {
        /*
         * Use offset style bit reads because "Index * AccessWidth" is
         * ensured to be less than 64-bits by AcpiHwValidateRegister().
         */
        Value64 = ACPI_GET_BITS (&Value, Index * AccessWidth,
            ACPI_MASK_BITS_ABOVE_64 (AccessWidth));

        if (BitOffset >= AccessWidth)
        {
            BitOffset -= AccessWidth;
        }
        else
        {
            if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
            {
                Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
                    Address + Index * ACPI_DIV_8 (AccessWidth),
                    Value64, AccessWidth);
            }
            else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
            {
                Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
                    Address + Index * ACPI_DIV_8 (AccessWidth),
                    (UINT32) Value64, AccessWidth);
            }
        }

        /*
         * Index * AccessWidth is ensured to be less than 32-bits by
         * AcpiHwValidateRegister().
         */
        BitWidth -= BitWidth > AccessWidth ? AccessWidth : BitWidth;
        Index++;
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_IO,
        "Wrote: %8.8X%8.8X width %2d   to %8.8X%8.8X (%s)\n",
        ACPI_FORMAT_UINT64 (Value), AccessWidth,
        ACPI_FORMAT_UINT64 (Address), AcpiUtGetRegionName (Reg->SpaceId)));

    return (Status);
}