x86: acpi: Move APIs unrelated to ACPI tables generation to a separate library

acpi_find_fadt(), acpi_find_wakeup_vector() and enter_acpi_mode()
are something unrelated to ACPI tables generation. Move these to
a separate library.

This also fixes several style issues reported by checkpatch in the
original codes.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Tested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
This commit is contained in:
Bin Meng 2018-07-18 21:42:15 -07:00
parent b37b7b2063
commit a0609a8d19
7 changed files with 153 additions and 128 deletions

View File

@ -24,6 +24,7 @@
#include <errno.h>
#include <malloc.h>
#include <syscon.h>
#include <asm/acpi.h>
#include <asm/acpi_s3.h>
#include <asm/acpi_table.h>
#include <asm/control_regs.h>

View File

@ -0,0 +1,41 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
*/
#ifndef __ASM_ACPI_H__
#define __ASM_ACPI_H__
struct acpi_fadt;
/**
* acpi_find_fadt() - find ACPI FADT table in the system memory
*
* This routine parses the ACPI table to locate the ACPI FADT table.
*
* @return: a pointer to the ACPI FADT table in the system memory
*/
struct acpi_fadt *acpi_find_fadt(void);
/**
* acpi_find_wakeup_vector() - find OS installed wake up vector address
*
* This routine parses the ACPI table to locate the wake up vector installed
* by the OS previously.
*
* @fadt: a pointer to the ACPI FADT table in the system memory
* @return: wake up vector address installed by the OS
*/
void *acpi_find_wakeup_vector(struct acpi_fadt *fadt);
/**
* enter_acpi_mode() - enter into ACPI mode
*
* This programs the ACPI-defined PM1_CNT register to enable SCI interrupt
* so that the whole system swiches to ACPI mode.
*
* @pm1_cnt: PM1_CNT register I/O address
*/
void enter_acpi_mode(int pm1_cnt);
#endif /* __ASM_ACPI_H__ */

View File

@ -317,15 +317,6 @@ int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base,
u16 seg_nr, u8 start, u8 end);
u32 acpi_fill_mcfg(u32 current);
void acpi_create_gnvs(struct acpi_global_nvs *gnvs);
/**
* enter_acpi_mode() - enter into ACPI mode
*
* This programs the ACPI-defined PM1_CNT register to enable SCI interrupt
* so that the whole system swiches to ACPI mode.
*
* @pm1_cnt: PM1_CNT register I/O address
*/
void enter_acpi_mode(int pm1_cnt);
ulong write_acpi_tables(ulong start);
/**
@ -336,22 +327,3 @@ ulong write_acpi_tables(ulong start);
* @return: ACPI RSDP table address
*/
ulong acpi_get_rsdp_addr(void);
/**
* acpi_find_fadt() - find ACPI FADT table in the sytem memory
*
* This routine parses the ACPI table to locate the ACPI FADT table.
*
* @return: a pointer to the ACPI FADT table in the system memory
*/
struct acpi_fadt *acpi_find_fadt(void);
/**
* acpi_find_wakeup_vector() - find OS installed wake up vector address
*
* This routine parses the ACPI table to locate the wake up vector installed
* by the OS previously.
*
* @return: wake up vector address installed by the OS
*/
void *acpi_find_wakeup_vector(struct acpi_fadt *);

View File

@ -33,6 +33,7 @@ obj-$(CONFIG_INTEL_MID) += scu.o
obj-y += sections.o
obj-y += sfi.o
obj-y += string.o
obj-y += acpi.o
obj-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.o
ifndef CONFIG_QEMU
obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o

108
arch/x86/lib/acpi.c Normal file
View File

@ -0,0 +1,108 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
*/
#include <common.h>
#include <asm/acpi_table.h>
#include <asm/io.h>
#include <asm/tables.h>
static struct acpi_rsdp *acpi_valid_rsdp(struct acpi_rsdp *rsdp)
{
if (strncmp((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0)
return NULL;
debug("Looking on %p for valid checksum\n", rsdp);
if (table_compute_checksum((void *)rsdp, 20) != 0)
return NULL;
debug("acpi rsdp checksum 1 passed\n");
if ((rsdp->revision > 1) &&
(table_compute_checksum((void *)rsdp, rsdp->length) != 0))
return NULL;
debug("acpi rsdp checksum 2 passed\n");
return rsdp;
}
struct acpi_fadt *acpi_find_fadt(void)
{
char *p, *end;
struct acpi_rsdp *rsdp = NULL;
struct acpi_rsdt *rsdt;
struct acpi_fadt *fadt = NULL;
int i;
/* Find RSDP */
for (p = (char *)ROM_TABLE_ADDR; p < (char *)ROM_TABLE_END; p += 16) {
rsdp = acpi_valid_rsdp((struct acpi_rsdp *)p);
if (rsdp)
break;
}
if (!rsdp)
return NULL;
debug("RSDP found at %p\n", rsdp);
rsdt = (struct acpi_rsdt *)(uintptr_t)rsdp->rsdt_address;
end = (char *)rsdt + rsdt->header.length;
debug("RSDT found at %p ends at %p\n", rsdt, end);
for (i = 0; ((char *)&rsdt->entry[i]) < end; i++) {
fadt = (struct acpi_fadt *)(uintptr_t)rsdt->entry[i];
if (strncmp((char *)fadt, "FACP", 4) == 0)
break;
fadt = NULL;
}
if (!fadt)
return NULL;
debug("FADT found at %p\n", fadt);
return fadt;
}
void *acpi_find_wakeup_vector(struct acpi_fadt *fadt)
{
struct acpi_facs *facs;
void *wake_vec;
debug("Trying to find the wakeup vector...\n");
facs = (struct acpi_facs *)(uintptr_t)fadt->firmware_ctrl;
if (!facs) {
debug("No FACS found, wake up from S3 not possible.\n");
return NULL;
}
debug("FACS found at %p\n", facs);
wake_vec = (void *)(uintptr_t)facs->firmware_waking_vector;
debug("OS waking vector is %p\n", wake_vec);
return wake_vec;
}
void enter_acpi_mode(int pm1_cnt)
{
u16 val = inw(pm1_cnt);
/*
* PM1_CNT register bit0 selects the power management event to be
* either an SCI or SMI interrupt. When this bit is set, then power
* management events will generate an SCI interrupt. When this bit
* is reset power management events will generate an SMI interrupt.
*
* Per ACPI spec, it is the responsibility of the hardware to set
* or reset this bit. OSPM always preserves this bit position.
*
* U-Boot does not support SMI. And we don't have plan to support
* anything running in SMM within U-Boot. To create a legacy-free
* system, and expose ourselves to OSPM as working under ACPI mode
* already, turn this bit on.
*/
outw(val | PM1_CNT_SCI_EN, pm1_cnt);
}

View File

@ -4,6 +4,7 @@
*/
#include <common.h>
#include <asm/acpi.h>
#include <asm/acpi_s3.h>
#include <asm/acpi_table.h>
#include <asm/post.h>

View File

@ -12,8 +12,8 @@
#include <dm/uclass-internal.h>
#include <version.h>
#include <asm/acpi/global_nvs.h>
#include <asm/acpi.h>
#include <asm/acpi_table.h>
#include <asm/io.h>
#include <asm/ioapic.h>
#include <asm/lapic.h>
#include <asm/mpspec.h>
@ -337,27 +337,6 @@ static void acpi_create_mcfg(struct acpi_mcfg *mcfg)
header->checksum = table_compute_checksum((void *)mcfg, header->length);
}
void enter_acpi_mode(int pm1_cnt)
{
u16 val = inw(pm1_cnt);
/*
* PM1_CNT register bit0 selects the power management event to be
* either an SCI or SMI interrupt. When this bit is set, then power
* management events will generate an SCI interrupt. When this bit
* is reset power management events will generate an SMI interrupt.
*
* Per ACPI spec, it is the responsibility of the hardware to set
* or reset this bit. OSPM always preserves this bit position.
*
* U-Boot does not support SMI. And we don't have plan to support
* anything running in SMM within U-Boot. To create a legacy-free
* system, and expose ourselves to OSPM as working under ACPI mode
* already, turn this bit on.
*/
outw(val | PM1_CNT_SCI_EN, pm1_cnt);
}
/*
* QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c
*/
@ -482,81 +461,3 @@ ulong acpi_get_rsdp_addr(void)
{
return acpi_rsdp_addr;
}
static struct acpi_rsdp *acpi_valid_rsdp(struct acpi_rsdp *rsdp)
{
if (strncmp((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0)
return NULL;
debug("Looking on %p for valid checksum\n", rsdp);
if (table_compute_checksum((void *)rsdp, 20) != 0)
return NULL;
debug("acpi rsdp checksum 1 passed\n");
if ((rsdp->revision > 1) &&
(table_compute_checksum((void *)rsdp, rsdp->length) != 0))
return NULL;
debug("acpi rsdp checksum 2 passed\n");
return rsdp;
}
struct acpi_fadt *acpi_find_fadt(void)
{
char *p, *end;
struct acpi_rsdp *rsdp = NULL;
struct acpi_rsdt *rsdt;
struct acpi_fadt *fadt = NULL;
int i;
/* Find RSDP */
for (p = (char *)ROM_TABLE_ADDR; p < (char *)ROM_TABLE_END; p += 16) {
rsdp = acpi_valid_rsdp((struct acpi_rsdp *)p);
if (rsdp)
break;
}
if (rsdp == NULL)
return NULL;
debug("RSDP found at %p\n", rsdp);
rsdt = (struct acpi_rsdt *)rsdp->rsdt_address;
end = (char *)rsdt + rsdt->header.length;
debug("RSDT found at %p ends at %p\n", rsdt, end);
for (i = 0; ((char *)&rsdt->entry[i]) < end; i++) {
fadt = (struct acpi_fadt *)rsdt->entry[i];
if (strncmp((char *)fadt, "FACP", 4) == 0)
break;
fadt = NULL;
}
if (fadt == NULL)
return NULL;
debug("FADT found at %p\n", fadt);
return fadt;
}
void *acpi_find_wakeup_vector(struct acpi_fadt *fadt)
{
struct acpi_facs *facs;
void *wake_vec;
debug("Trying to find the wakeup vector...\n");
facs = (struct acpi_facs *)fadt->firmware_ctrl;
if (facs == NULL) {
debug("No FACS found, wake up from S3 not possible.\n");
return NULL;
}
debug("FACS found at %p\n", facs);
wake_vec = (void *)facs->firmware_waking_vector;
debug("OS waking vector is %p\n", wake_vec);
return wake_vec;
}