Exemple #1
0
void *
acpi_find_table(const char *sig)
{
	ACPI_PHYSICAL_ADDRESS rsdp_ptr;
	ACPI_TABLE_RSDP *rsdp;
	ACPI_TABLE_XSDT *xsdt;
	ACPI_TABLE_HEADER *table;
	UINT64 addr;
	u_int i, count;

	if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
		return (NULL);

	rsdp = (ACPI_TABLE_RSDP *)IA64_PHYS_TO_RR7(rsdp_ptr);
	xsdt = (ACPI_TABLE_XSDT *)IA64_PHYS_TO_RR7(rsdp->XsdtPhysicalAddress);

	count = (UINT64 *)((char *)xsdt + xsdt->Header.Length) -
	    xsdt->TableOffsetEntry;

	for (i = 0; i < count; i++) {
		addr = xsdt->TableOffsetEntry[i];
		table = (ACPI_TABLE_HEADER *)IA64_PHYS_TO_RR7(addr);

		if (strncmp(table->Signature, sig, ACPI_NAME_SIZE) != 0)
			continue;
		if (ACPI_FAILURE(AcpiTbChecksum((void *)table, table->Length)))
			continue;

		return (table);
	}

	return (NULL);
}
Exemple #2
0
ACPI_STATUS
AcpiInitializeTables (
    ACPI_TABLE_DESC         *InitialTableArray,
    UINT32                  InitialTableCount,
    BOOLEAN                 AllowResize)
{
    ACPI_PHYSICAL_ADDRESS   RsdpAddress;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (AcpiInitializeTables);


    /*
     * Setup the Root Table Array and allocate the table array
     * if requested
     */
    if (!InitialTableArray)
    {
        Status = AcpiAllocateRootTable (InitialTableCount);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }
    }
    else
    {
        /* Root Table Array has been statically allocated by the host */

        memset (InitialTableArray, 0,
            (ACPI_SIZE) InitialTableCount * sizeof (ACPI_TABLE_DESC));

        AcpiGbl_RootTableList.Tables = InitialTableArray;
        AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
        AcpiGbl_RootTableList.Flags = ACPI_ROOT_ORIGIN_UNKNOWN;
        if (AllowResize)
        {
            AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
        }
    }

    /* Get the address of the RSDP */

    RsdpAddress = AcpiOsGetRootPointer ();
    if (!RsdpAddress)
    {
        return_ACPI_STATUS (AE_NOT_FOUND);
    }

    /*
     * Get the root table (RSDT or XSDT) and extract all entries to the local
     * Root Table Array. This array contains the information of the RSDT/XSDT
     * in a common, more useable format.
     */
    Status = AcpiTbParseRootTable (RsdpAddress);
    return_ACPI_STATUS (Status);
}
Exemple #3
0
static PyObject *bits_acpi_get_root_pointer(PyObject *self, PyObject *args)
{
    ACPI_TABLE_RSDP *rsdp;

    if (acpica_init() != GRUB_ERR_NONE)
        return PyErr_Format(PyExc_RuntimeError, "ACPICA module failed to initialize.");

    rsdp = (ACPI_TABLE_RSDP *)AcpiOsGetRootPointer();

    if (rsdp)
        return Py_BuildValue("k", (unsigned long)rsdp);

    return Py_BuildValue("");
}
Exemple #4
0
/*
 * Count the number of local SAPIC entries in the APIC table. Every enabled
 * entry corresponds to a processor.
 */
int
ia64_count_cpus(void)
{
	ACPI_PHYSICAL_ADDRESS rsdp_ptr;
	ACPI_MADT_LOCAL_SAPIC *entry;
	ACPI_TABLE_MADT *table;
	ACPI_TABLE_RSDP *rsdp;
	ACPI_TABLE_XSDT *xsdt;
	char *end, *p;
	int cpus, t, tables;

	if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
		return (0);

	rsdp = (ACPI_TABLE_RSDP *)IA64_PHYS_TO_RR7(rsdp_ptr);
	xsdt = (ACPI_TABLE_XSDT *)IA64_PHYS_TO_RR7(rsdp->XsdtPhysicalAddress);

	tables = (UINT64 *)((char *)xsdt + xsdt->Header.Length) -
	    xsdt->TableOffsetEntry;

	cpus = 0;

	for (t = 0; t < tables; t++) {
		table = (ACPI_TABLE_MADT *)
		    IA64_PHYS_TO_RR7(xsdt->TableOffsetEntry[t]);

		if (strncmp(table->Header.Signature, ACPI_SIG_MADT,
		    ACPI_NAME_SIZE) != 0 ||
		    ACPI_FAILURE(AcpiTbChecksum((void *)table,
			table->Header.Length)))
			continue;

		end = (char *)table + table->Header.Length;
		p = (char *)(table + 1);
		while (p < end) {
			entry = (ACPI_MADT_LOCAL_SAPIC *)p;

			if (entry->Header.Type == ACPI_MADT_TYPE_LOCAL_SAPIC &&
			    (entry->LapicFlags & ACPI_MADT_ENABLED))
				cpus++;

			p += entry->Header.Length;
		}
	}

	return (cpus);
}
Exemple #5
0
static PyObject *bits_acpi_get_rsdt(PyObject *self, PyObject *args)
{
    ACPI_TABLE_RSDP *rsdp;
    ACPI_TABLE_RSDT *rsdt;

    if (acpica_init() != GRUB_ERR_NONE)
        return PyErr_Format(PyExc_RuntimeError, "ACPICA module failed to initialize.");

    rsdp = (ACPI_TABLE_RSDP *)AcpiOsGetRootPointer();

    if (rsdp) {
        rsdt = (ACPI_TABLE_RSDT *)(unsigned long)rsdp->RsdtPhysicalAddress;
        if (rsdt)
            return Py_BuildValue("s#", rsdt, (Py_ssize_t)rsdt->Header.Length);
    }
    return Py_BuildValue("");
}
Exemple #6
0
static PyObject *bits_acpi_get_rsdp(PyObject *self, PyObject *args)
{
    ACPI_TABLE_RSDP *rsdp;
    Py_ssize_t length = 0;

    if (acpica_init() != GRUB_ERR_NONE)
        return PyErr_Format(PyExc_RuntimeError, "ACPICA module failed to initialize.");

    rsdp = (ACPI_TABLE_RSDP *)AcpiOsGetRootPointer();

    if (rsdp) {
        if (rsdp->Revision == 0)
            length = sizeof(ACPI_RSDP_COMMON);
        else if (rsdp->Revision >= 2)
            length = rsdp->Length;
        if (length)
            return Py_BuildValue("s#", rsdp, length);
    }
    return Py_BuildValue("");
}
Exemple #7
0
static PyObject *bits_acpi_get_xsdt(PyObject *self, PyObject *args)
{
    ACPI_TABLE_RSDP *rsdp;
    ACPI_TABLE_XSDT *xsdt;

    if (acpica_init() != GRUB_ERR_NONE)
        return PyErr_Format(PyExc_RuntimeError, "ACPICA module failed to initialize.");

    rsdp = (ACPI_TABLE_RSDP *)AcpiOsGetRootPointer();

    if (rsdp) {
        if (rsdp->Revision >= 2) {
#if defined(GRUB_TARGET_CPU_I386)
            if (rsdp->XsdtPhysicalAddress > GRUB_UINT_MAX)
                return PyErr_Format(PyExc_RuntimeError, "XSDT located above 4G; cannot access on 32-bit");
#endif
            xsdt = (ACPI_TABLE_XSDT *)(unsigned long)rsdp->XsdtPhysicalAddress;
            if (xsdt)
                return Py_BuildValue("s#", xsdt, (Py_ssize_t)xsdt->Header.Length);
        }
    }
    return Py_BuildValue("");
}
Exemple #8
0
void
ia64_probe_sapics(void)
{
	ACPI_PHYSICAL_ADDRESS rsdp_ptr;
	ACPI_SUBTABLE_HEADER *entry;
	ACPI_TABLE_MADT *table;
	ACPI_TABLE_RSDP *rsdp;
	ACPI_TABLE_XSDT *xsdt;
	char *end, *p;
	int t, tables;

	if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
		return;

	rsdp = (ACPI_TABLE_RSDP *)IA64_PHYS_TO_RR7(rsdp_ptr);
	xsdt = (ACPI_TABLE_XSDT *)IA64_PHYS_TO_RR7(rsdp->XsdtPhysicalAddress);

	tables = (UINT64 *)((char *)xsdt + xsdt->Header.Length) -
	    xsdt->TableOffsetEntry;

	for (t = 0; t < tables; t++) {
		table = (ACPI_TABLE_MADT *)
		    IA64_PHYS_TO_RR7(xsdt->TableOffsetEntry[t]);

		if (bootverbose)
			printf("Table '%c%c%c%c' at %p\n",
			    table->Header.Signature[0],
			    table->Header.Signature[1],
			    table->Header.Signature[2],
			    table->Header.Signature[3], table);

		if (strncmp(table->Header.Signature, ACPI_SIG_MADT,
		    ACPI_NAME_SIZE) != 0 ||
		    ACPI_FAILURE(AcpiTbChecksum((void *)table,
		    table->Header.Length)))
			continue;

		/* Save the address of the processor interrupt block. */
		if (bootverbose)
			printf("\tLocal APIC address=0x%x\n", table->Address);
		ia64_lapic_addr = table->Address;

		end = (char *)table + table->Header.Length;
		p = (char *)(table + 1);
		while (p < end) {
			entry = (ACPI_SUBTABLE_HEADER *)p;

			if (bootverbose)
				print_entry(entry);

			switch (entry->Type) {
			case ACPI_MADT_TYPE_IO_SAPIC: {
				ACPI_MADT_IO_SAPIC *sapic =
				    (ACPI_MADT_IO_SAPIC *)entry;
				sapic_create(sapic->Id, sapic->GlobalIrqBase,
				    sapic->Address);
				break;
			}

			case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: {
				ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic =
				    (ACPI_MADT_LOCAL_APIC_OVERRIDE *)entry;
				ia64_lapic_addr = lapic->Address;
				break;
			}

#ifdef SMP
			case ACPI_MADT_TYPE_LOCAL_SAPIC: {
				ACPI_MADT_LOCAL_SAPIC *sapic =
				    (ACPI_MADT_LOCAL_SAPIC *)entry;
				if (sapic->LapicFlags & ACPI_MADT_ENABLED)
					cpu_mp_add(sapic->ProcessorId,
					    sapic->Id, sapic->Eid);
				break;
			}
#endif

			default:
				break;
			}

			p += entry->Length;
		}
	}
}
Exemple #9
0
ACPI_STATUS
AcpiGetFirmwareTable (
    ACPI_STRING             Signature,
    UINT32                  Instance,
    UINT32                  Flags,
    ACPI_TABLE_HEADER       **TablePointer)
{
    ACPI_POINTER            RsdpAddress;
    ACPI_POINTER            Address;
    ACPI_STATUS             Status;
    ACPI_TABLE_HEADER       Header;
    ACPI_TABLE_DESC         TableInfo;
    ACPI_TABLE_DESC         RsdtInfo;
    UINT32                  TableCount;
    UINT32                  i;
    UINT32                  j;


    ACPI_FUNCTION_TRACE ("AcpiGetFirmwareTable");


    /*
     * Ensure that at least the table manager is initialized.  We don't
     * require that the entire ACPI subsystem is up for this interface
     */

    /*
     *  If we have a buffer, we must have a length too
     */
    if ((Instance == 0)                 ||
        (!Signature)                    ||
        (!TablePointer))
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    RsdtInfo.Pointer = NULL;

    if (!AcpiGbl_RSDP)
    {
        /* Get the RSDP */

        Status = AcpiOsGetRootPointer (Flags, &RsdpAddress);
        if (ACPI_FAILURE (Status))
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP  not found\n"));
            return_ACPI_STATUS (AE_NO_ACPI_TABLES);
        }

        /* Map and validate the RSDP */

        if ((Flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING)
        {
            Status = AcpiOsMapMemory (RsdpAddress.Pointer.Physical, sizeof (RSDP_DESCRIPTOR),
                                        (void **) &AcpiGbl_RSDP);
            if (ACPI_FAILURE (Status))
            {
                return_ACPI_STATUS (Status);
            }
        }
        else
        {
            AcpiGbl_RSDP = RsdpAddress.Pointer.Logical;
        }

        /*
         *  The signature and checksum must both be correct
         */
        if (ACPI_STRNCMP ((char *) AcpiGbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0)
        {
            /* Nope, BAD Signature */

            return_ACPI_STATUS (AE_BAD_SIGNATURE);
        }

        if (AcpiTbChecksum (AcpiGbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0)
        {
            /* Nope, BAD Checksum */

            return_ACPI_STATUS (AE_BAD_CHECKSUM);
        }
    }

    /* Get the RSDT and validate it */

    AcpiTbGetRsdtAddress (&Address);

    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
        "RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
        AcpiGbl_RSDP,
        ACPI_HIDWORD (Address.Pointer.Value),
        ACPI_LODWORD (Address.Pointer.Value)));

    /* Insert ProcessorMode flags */

    Address.PointerType |= Flags;

    Status = AcpiTbGetTable (&Address, &RsdtInfo);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    Status = AcpiTbValidateRsdt (RsdtInfo.Pointer);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    /* Get the number of table pointers within the RSDT */

    TableCount = AcpiTbGetTableCount (AcpiGbl_RSDP, RsdtInfo.Pointer);

    Address.PointerType = AcpiGbl_TableFlags | Flags;

    /*
     * Search the RSDT/XSDT for the correct instance of the
     * requested table
     */
    for (i = 0, j = 0; i < TableCount; i++)
    {
        /* Get the next table pointer, handle RSDT vs. XSDT */

        if (AcpiGbl_RSDP->Revision < 2)
        {
            Address.Pointer.Value = ((RSDT_DESCRIPTOR *) RsdtInfo.Pointer)->TableOffsetEntry[i];
        }
        else
        {
            Address.Pointer.Value = ACPI_GET_ADDRESS (
                ((XSDT_DESCRIPTOR *) RsdtInfo.Pointer)->TableOffsetEntry[i]);
        }

        /* Get the table header */

        Status = AcpiTbGetTableHeader (&Address, &Header);
        if (ACPI_FAILURE (Status))
        {
            goto Cleanup;
        }

        /* Compare table signatures and table instance */

        if (!ACPI_STRNCMP (Header.Signature, Signature, ACPI_NAME_SIZE))
        {
            /* An instance of the table was found */

            j++;
            if (j >= Instance)
            {
                /* Found the correct instance, get the entire table */

                Status = AcpiTbGetTableBody (&Address, &Header, &TableInfo);
                if (ACPI_FAILURE (Status))
                {
                    goto Cleanup;
                }

                *TablePointer = TableInfo.Pointer;
                goto Cleanup;
            }
        }
    }

    /* Did not find the table */

    Status = AE_NOT_EXIST;


Cleanup:
    AcpiOsUnmapMemory (RsdtInfo.Pointer, (ACPI_SIZE) RsdtInfo.Pointer->Length);
    return_ACPI_STATUS (Status);
}
Exemple #10
0
/*
 * Return the physical address of the requested table or zero if one
 * is not found.
 */
vm_paddr_t
acpi_find_table(const char *sig)
{
	ACPI_PHYSICAL_ADDRESS rsdp_ptr;
	ACPI_TABLE_RSDP *rsdp;
	ACPI_TABLE_XSDT *xsdt;
	ACPI_TABLE_HEADER *table;
	vm_paddr_t addr;
	int i, count;

	if (resource_disabled("acpi", 0))
		return (0);

	/*
	 * Map in the RSDP.  Since ACPI uses AcpiOsMapMemory() which in turn
	 * calls pmap_mapbios() to find the RSDP, we assume that we can use
	 * pmap_mapbios() to map the RSDP.
	 */
	if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
		return (0);
	rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP));
	if (rsdp == NULL) {
		if (bootverbose)
			printf("ACPI: Failed to map RSDP\n");
		return (0);
	}

	addr = 0;
	if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
		/*
		 * AcpiOsGetRootPointer only verifies the checksum for
		 * the version 1.0 portion of the RSDP.  Version 2.0 has
		 * an additional checksum that we verify first.
		 */
		if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) {
			if (bootverbose)
				printf("ACPI: RSDP failed extended checksum\n");
			return (0);
		}
		xsdt = map_table(rsdp->XsdtPhysicalAddress, 2, ACPI_SIG_XSDT);
		if (xsdt == NULL) {
			if (bootverbose)
				printf("ACPI: Failed to map XSDT\n");
			pmap_unmapbios((vm_offset_t)rsdp,
			    sizeof(ACPI_TABLE_RSDP));
			return (0);
		}
		count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
		    sizeof(UINT64);
		for (i = 0; i < count; i++)
			if (probe_table(xsdt->TableOffsetEntry[i], sig)) {
				addr = xsdt->TableOffsetEntry[i];
				break;
			}
		acpi_unmap_table(xsdt);
	}
	pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP));

	if (addr == 0) {
		if (bootverbose)
			printf("ACPI: No %s table found\n", sig);
		return (0);
	}
	if (bootverbose)
		printf("%s: Found table at 0x%jx\n", sig, (uintmax_t)addr);

	/*
	 * Verify that we can map the full table and that its checksum is
	 * correct, etc.
	 */
	table = map_table(addr, 0, sig);
	if (table == NULL)
		return (0);
	acpi_unmap_table(table);

	return (addr);
}
Exemple #11
0
ACPI_STATUS
AcpiLoadTables (void)
{
    ACPI_POINTER            RsdpAddress;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE ("AcpiLoadTables");


    /* Get the RSDP */

    Status = AcpiOsGetRootPointer (ACPI_LOGICAL_ADDRESSING,
                    &RsdpAddress);
    if (ACPI_FAILURE (Status))
    {
        ACPI_REPORT_ERROR (("AcpiLoadTables: Could not get RSDP, %s\n",
                        AcpiFormatException (Status)));
        goto ErrorExit;
    }

    /* Map and validate the RSDP */

    AcpiGbl_TableFlags = RsdpAddress.PointerType;

    Status = AcpiTbVerifyRsdp (&RsdpAddress);
    if (ACPI_FAILURE (Status))
    {
        ACPI_REPORT_ERROR (("AcpiLoadTables: RSDP Failed validation: %s\n",
                        AcpiFormatException (Status)));
        goto ErrorExit;
    }

    /* Get the RSDT via the RSDP */

    Status = AcpiTbGetTableRsdt ();
    if (ACPI_FAILURE (Status))
    {
        ACPI_REPORT_ERROR (("AcpiLoadTables: Could not load RSDT: %s\n",
                        AcpiFormatException (Status)));
        goto ErrorExit;
    }

    /* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */

    Status = AcpiTbGetRequiredTables ();
    if (ACPI_FAILURE (Status))
    {
        ACPI_REPORT_ERROR (("AcpiLoadTables: Error getting required tables (DSDT/FADT/FACS): %s\n",
                        AcpiFormatException (Status)));
        goto ErrorExit;
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));


    /* Load the namespace from the tables */

    Status = AcpiNsLoadNamespace ();
    if (ACPI_FAILURE (Status))
    {
        ACPI_REPORT_ERROR (("AcpiLoadTables: Could not load namespace: %s\n",
                        AcpiFormatException (Status)));
        goto ErrorExit;
    }

    return_ACPI_STATUS (AE_OK);


ErrorExit:
    ACPI_REPORT_ERROR (("AcpiLoadTables: Could not load tables: %s\n",
                    AcpiFormatException (Status)));

    return_ACPI_STATUS (Status);
}
Exemple #12
0
/*
 * Look for an ACPI Multiple APIC Description Table ("APIC")
 */
static int
madt_probe(void)
{
	ACPI_POINTER rsdp_ptr;
	RSDP_DESCRIPTOR *rsdp;
	RSDT_DESCRIPTOR *rsdt;
	XSDT_DESCRIPTOR *xsdt;
	int i, count;

	if (resource_disabled("acpi", 0))
		return (ENXIO);

	/*
	 * Map in the RSDP.  Since ACPI uses AcpiOsMapMemory() which in turn
	 * calls pmap_mapdev() to find the RSDP, we assume that we can use
	 * pmap_mapdev() to map the RSDP.
	 */
	if (AcpiOsGetRootPointer(ACPI_LOGICAL_ADDRESSING, &rsdp_ptr) != AE_OK)
		return (ENXIO);
#ifdef __i386__
	KASSERT(rsdp_ptr.Pointer.Physical < KERNLOAD, ("RSDP too high"));
#endif
	rsdp = pmap_mapdev(rsdp_ptr.Pointer.Physical, sizeof(RSDP_DESCRIPTOR));
	if (rsdp == NULL) {
		if (bootverbose)
			printf("MADT: Failed to map RSDP\n");
		return (ENXIO);
	}

	/*
	 * For ACPI < 2.0, use the RSDT.  For ACPI >= 2.0, use the XSDT.
	 * We map the XSDT and RSDT at page 1 in the crashdump area.
	 * Page 0 is used to map in the headers of candidate ACPI tables.
	 */
	if (rsdp->Revision >= 2) {
		xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 1, XSDT_SIG);
		if (xsdt == NULL) {
			if (bootverbose)
				printf("MADT: Failed to map XSDT\n");
			return (ENXIO);
		}
		count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
		    sizeof(UINT64);
		for (i = 0; i < count; i++)
			if (madt_probe_table(xsdt->TableOffsetEntry[i]))
				break;
		madt_unmap_table(xsdt);
	} else {
		rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 1, RSDT_SIG);
		if (rsdt == NULL) {
			if (bootverbose)
				printf("MADT: Failed to map RSDT\n");
			return (ENXIO);
		}
		count = (rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
		    sizeof(UINT32);
		for (i = 0; i < count; i++)
			if (madt_probe_table(rsdt->TableOffsetEntry[i]))
				break;
		madt_unmap_table(rsdt);
	}
	pmap_unmapdev((vm_offset_t)rsdp, sizeof(RSDP_DESCRIPTOR));
	if (madt_physaddr == 0) {
		if (bootverbose)
			printf("MADT: No MADT table found\n");
		return (ENXIO);
	}
	if (bootverbose)
		printf("MADT: Found table at 0x%jx\n",
		    (uintmax_t)madt_physaddr);

	return (0);
}