Example #1
0
void acpi_resume(struct acpi_fadt *fadt)
{
	void *wake_vec;

	/* Turn on ACPI mode for S3 */
	enter_acpi_mode(fadt->pm1a_cnt_blk);

	wake_vec = acpi_find_wakeup_vector(fadt);

	/*
	 * Restore the memory content starting from address 0x1000 which is
	 * used for the real mode interrupt handler stubs.
	 */
	memcpy((void *)0x1000, (const void *)gd->arch.backup_mem,
	       S3_RESERVE_SIZE);

	post_code(POST_OS_RESUME);
	acpi_jump_to_wakeup(wake_vec);
}
Example #2
0
/*
 * QEMU's version of write_acpi_tables is defined in
 * arch/x86/cpu/qemu/acpi_table.c
 */
u32 write_acpi_tables(u32 start)
{
	u32 current;
	struct acpi_rsdp *rsdp;
	struct acpi_rsdt *rsdt;
	struct acpi_xsdt *xsdt;
	struct acpi_facs *facs;
	struct acpi_table_header *dsdt;
	struct acpi_fadt *fadt;
	struct acpi_mcfg *mcfg;
	struct acpi_madt *madt;

	current = start;

	/* Align ACPI tables to 16 byte */
	current = ALIGN(current, 16);

	debug("ACPI: Writing ACPI tables at %x\n", start);

	/* We need at least an RSDP and an RSDT Table */
	rsdp = (struct acpi_rsdp *)current;
	current += sizeof(struct acpi_rsdp);
	current = ALIGN(current, 16);
	rsdt = (struct acpi_rsdt *)current;
	current += sizeof(struct acpi_rsdt);
	current = ALIGN(current, 16);
	xsdt = (struct acpi_xsdt *)current;
	current += sizeof(struct acpi_xsdt);
	/*
	 * Per ACPI spec, the FACS table address must be aligned to a 64 byte
	 * boundary (Windows checks this, but Linux does not).
	 */
	current = ALIGN(current, 64);

	/* clear all table memory */
	memset((void *)start, 0, current - start);

	acpi_write_rsdp(rsdp, rsdt, xsdt);
	acpi_write_rsdt(rsdt);
	acpi_write_xsdt(xsdt);

	debug("ACPI:    * FACS\n");
	facs = (struct acpi_facs *)current;
	current += sizeof(struct acpi_facs);
	current = ALIGN(current, 16);

	acpi_create_facs(facs);

	debug("ACPI:    * DSDT\n");
	dsdt = (struct acpi_table_header *)current;
	memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header));
	current += sizeof(struct acpi_table_header);
	memcpy((char *)current,
	       (char *)&AmlCode + sizeof(struct acpi_table_header),
	       dsdt->length - sizeof(struct acpi_table_header));
	current += dsdt->length - sizeof(struct acpi_table_header);
	current = ALIGN(current, 16);

	debug("ACPI:    * FADT\n");
	fadt = (struct acpi_fadt *)current;
	current += sizeof(struct acpi_fadt);
	current = ALIGN(current, 16);
	acpi_create_fadt(fadt, facs, dsdt);
	acpi_add_table(rsdp, fadt);

	debug("ACPI:    * MADT\n");
	madt = (struct acpi_madt *)current;
	acpi_create_madt(madt);
	current += madt->header.length;
	acpi_add_table(rsdp, madt);
	current = ALIGN(current, 16);

	debug("ACPI:    * MCFG\n");
	mcfg = (struct acpi_mcfg *)current;
	acpi_create_mcfg(mcfg);
	current += mcfg->header.length;
	acpi_add_table(rsdp, mcfg);
	current = ALIGN(current, 16);

	debug("current = %x\n", current);

	debug("ACPI: done\n");

	/*
	 * Other than waiting for OSPM to request us to switch to ACPI mode,
	 * do it by ourselves, since SMI will not be triggered.
	 */
	enter_acpi_mode(fadt->pm1a_cnt_blk);

	return current;
}
Example #3
0
/*
 * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c
 */
ulong write_acpi_tables(ulong start)
{
	u32 current;
	struct acpi_rsdp *rsdp;
	struct acpi_rsdt *rsdt;
	struct acpi_xsdt *xsdt;
	struct acpi_facs *facs;
	struct acpi_table_header *dsdt;
	struct acpi_fadt *fadt;
	struct acpi_mcfg *mcfg;
	struct acpi_madt *madt;
	int i;

	current = start;

	/* Align ACPI tables to 16 byte */
	current = ALIGN(current, 16);

	debug("ACPI: Writing ACPI tables at %lx\n", start);

	/* We need at least an RSDP and an RSDT Table */
	rsdp = (struct acpi_rsdp *)current;
	current += sizeof(struct acpi_rsdp);
	current = ALIGN(current, 16);
	rsdt = (struct acpi_rsdt *)current;
	current += sizeof(struct acpi_rsdt);
	current = ALIGN(current, 16);
	xsdt = (struct acpi_xsdt *)current;
	current += sizeof(struct acpi_xsdt);
	/*
	 * Per ACPI spec, the FACS table address must be aligned to a 64 byte
	 * boundary (Windows checks this, but Linux does not).
	 */
	current = ALIGN(current, 64);

	/* clear all table memory */
	memset((void *)start, 0, current - start);

	acpi_write_rsdp(rsdp, rsdt, xsdt);
	acpi_write_rsdt(rsdt);
	acpi_write_xsdt(xsdt);

	debug("ACPI:    * FACS\n");
	facs = (struct acpi_facs *)current;
	current += sizeof(struct acpi_facs);
	current = ALIGN(current, 16);

	acpi_create_facs(facs);

	debug("ACPI:    * DSDT\n");
	dsdt = (struct acpi_table_header *)current;
	memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header));
	current += sizeof(struct acpi_table_header);
	memcpy((char *)current,
	       (char *)&AmlCode + sizeof(struct acpi_table_header),
	       dsdt->length - sizeof(struct acpi_table_header));
	current += dsdt->length - sizeof(struct acpi_table_header);
	current = ALIGN(current, 16);

	/* Pack GNVS into the ACPI table area */
	for (i = 0; i < dsdt->length; i++) {
		u32 *gnvs = (u32 *)((u32)dsdt + i);
		if (*gnvs == ACPI_GNVS_ADDR) {
			debug("Fix up global NVS in DSDT to 0x%08x\n", current);
			*gnvs = current;
			break;
		}
	}

	/* Update DSDT checksum since we patched the GNVS address */
	dsdt->checksum = 0;
	dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length);

	/* Fill in platform-specific global NVS variables */
	acpi_create_gnvs((struct acpi_global_nvs *)current);
	current += sizeof(struct acpi_global_nvs);
	current = ALIGN(current, 16);

	debug("ACPI:    * FADT\n");
	fadt = (struct acpi_fadt *)current;
	current += sizeof(struct acpi_fadt);
	current = ALIGN(current, 16);
	acpi_create_fadt(fadt, facs, dsdt);
	acpi_add_table(rsdp, fadt);

	debug("ACPI:    * MADT\n");
	madt = (struct acpi_madt *)current;
	acpi_create_madt(madt);
	current += madt->header.length;
	acpi_add_table(rsdp, madt);
	current = ALIGN(current, 16);

	debug("ACPI:    * MCFG\n");
	mcfg = (struct acpi_mcfg *)current;
	acpi_create_mcfg(mcfg);
	current += mcfg->header.length;
	acpi_add_table(rsdp, mcfg);
	current = ALIGN(current, 16);

	debug("current = %x\n", current);

	acpi_rsdp_addr = (unsigned long)rsdp;
	debug("ACPI: done\n");

	/* Don't touch ACPI hardware on HW reduced platforms */
	if (fadt->flags & ACPI_FADT_HW_REDUCED_ACPI)
		return current;

	/*
	 * Other than waiting for OSPM to request us to switch to ACPI mode,
	 * do it by ourselves, since SMI will not be triggered.
	 */
	enter_acpi_mode(fadt->pm1a_cnt_blk);

	return current;
}