Skip to content

Commit 86fe2e0

Browse files
jsun26intelacrnsi
authored andcommitted
HV: split acpi.c
Split acpi.c to acpi_base.c and acpi_ext.c. The former one will go FuSa and the later one will not; Tracked-On: #3107 Signed-off-by: Victor Sun <victor.sun@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent cbab1f8 commit 86fe2e0

File tree

3 files changed

+163
-125
lines changed

3 files changed

+163
-125
lines changed

hypervisor/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,9 @@ endif
161161
ifeq ($(CONFIG_DMAR_PARSE_ENABLED),y)
162162
C_SRCS += acpi_parser/dmar_parse.c
163163
endif
164+
C_SRCS += acpi_parser/acpi_ext.c
164165

165-
C_SRCS += boot/acpi.c
166+
C_SRCS += boot/acpi_base.c
166167
C_SRCS += boot/dmar_info.c
167168
C_SRCS += boot/cmdline.c
168169
C_SRCS += boot/guest/vboot_wrapper.c

hypervisor/acpi_parser/acpi_ext.c

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*-
2+
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3+
*
4+
* Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org>
5+
* Copyright (c) 2018 Intel Corporation
6+
* All rights reserved.
7+
*
8+
* Redistribution and use in source and binary forms, with or without
9+
* modification, are permitted provided that the following conditions
10+
* are met:
11+
* 1. Redistributions of source code must retain the above copyright
12+
* notice, this list of conditions and the following disclaimer.
13+
* 2. Redistributions in binary form must reproduce the above copyright
14+
* notice, this list of conditions and the following disclaimer in the
15+
* documentation and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20+
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27+
* SUCH DAMAGE.
28+
*/
29+
#include <types.h>
30+
#include <rtl.h>
31+
#include <vboot.h>
32+
#include "acpi.h"
33+
#include <pgtable.h>
34+
#include <ioapic.h>
35+
#include <logmsg.h>
36+
#include <host_pm.h>
37+
#include <acrn_common.h>
38+
39+
#ifndef CONFIG_CONSTANT_ACPI
40+
/* Per ACPI spec:
41+
* There are two fundamental types of ACPI tables:
42+
*
43+
* Tables that contain AML code produced from the ACPI Source Language (ASL).
44+
* These include the DSDT, any SSDTs, and sometimes OEM-specific tables (OEMx).
45+
*
46+
* Tables that contain simple data and no AML byte code. These types of tables
47+
* are known as ACPI Data Tables. They include tables such as the FADT, MADT,
48+
* ECDT, SRAT, etc. -essentially any table other than a DSDT or SSDT.
49+
*
50+
* The second type of table, the ACPI Data Table, could be parsed here.
51+
*
52+
* When ACRN go FuSa, the platform ACPI data should be fixed. The MACRO of
53+
* CONFIG_CONSTANT_ACPI will be defined, then this code is not needed.
54+
*/
55+
56+
#define ACPI_SIG_FACS 0x53434146U /* "FACS" */
57+
#define ACPI_SIG_FADT "FACP" /* Fixed ACPI Description Table */
58+
59+
/* FACP field offsets */
60+
#define OFFSET_FACS_ADDR 36U
61+
#define OFFSET_FACS_X_ADDR 132U
62+
#define OFFSET_PM1A_EVT 148U
63+
#define OFFSET_PM1A_CNT 172U
64+
65+
/* FACS field offsets */
66+
#define OFFSET_FACS_SIGNATURE 0U
67+
#define OFFSET_FACS_LENGTH 4U
68+
#define OFFSET_WAKE_VECTOR_32 12U
69+
#define OFFSET_WAKE_VECTOR_64 24U
70+
71+
/* get a dword value from given table and its offset */
72+
static inline uint32_t get_acpi_dt_dword(const uint8_t *dt_addr, uint32_t dt_offset)
73+
{
74+
return *(uint32_t *)(dt_addr + dt_offset);
75+
}
76+
77+
/* get a qword value from given table and its offset */
78+
static inline uint64_t get_acpi_dt_qword(const uint8_t *dt_addr, uint32_t dt_offset)
79+
{
80+
return *(uint64_t *)(dt_addr + dt_offset);
81+
}
82+
83+
struct packed_gas {
84+
uint8_t space_id;
85+
uint8_t bit_width;
86+
uint8_t bit_offset;
87+
uint8_t access_size;
88+
uint64_t address;
89+
} __attribute__((packed));
90+
91+
/* get a GAS struct from given table and its offset.
92+
* ACPI table stores packed gas, but it is not guaranteed that
93+
* struct acpi_generic_address is packed, so do not use memcpy in function.
94+
* @pre dt_addr != NULL && gas != NULL
95+
*/
96+
static inline void get_acpi_dt_gas(const uint8_t *dt_addr, uint32_t dt_offset, struct acpi_generic_address *gas)
97+
{
98+
struct packed_gas *dt_gas = (struct packed_gas *)(dt_addr + dt_offset);
99+
100+
gas->space_id = dt_gas->space_id;
101+
gas->bit_width = dt_gas->bit_width;
102+
gas->bit_offset = dt_gas->bit_offset;
103+
gas->access_size = dt_gas->access_size;
104+
gas->address = dt_gas->address;
105+
}
106+
107+
/* @pre facp_addr != NULL */
108+
static void *get_facs_table(const uint8_t *facp_addr)
109+
{
110+
uint8_t *facs_addr, *facs_x_addr;
111+
uint32_t signature, length;
112+
113+
facs_addr = (uint8_t *)(uint64_t)get_acpi_dt_dword(facp_addr, OFFSET_FACS_ADDR);
114+
115+
facs_x_addr = (uint8_t *)get_acpi_dt_qword(facp_addr, OFFSET_FACS_X_ADDR);
116+
117+
if (facs_x_addr != NULL) {
118+
facs_addr = facs_x_addr;
119+
}
120+
121+
if (facs_addr != NULL) {
122+
signature = get_acpi_dt_dword(facs_addr, OFFSET_FACS_SIGNATURE);
123+
124+
if (signature != ACPI_SIG_FACS) {
125+
facs_addr = NULL;
126+
} else {
127+
length = get_acpi_dt_dword(facs_addr, OFFSET_FACS_LENGTH);
128+
129+
if (length < 64U) {
130+
facs_addr = NULL;
131+
}
132+
}
133+
}
134+
return (void *)facs_addr;
135+
}
136+
137+
/* put all ACPI fix up code here */
138+
void acpi_fixup(void)
139+
{
140+
uint8_t *facp_addr, *facs_addr;
141+
struct acpi_generic_address pm1a_cnt, pm1a_evt;
142+
struct pm_s_state_data *sx_data = get_host_sstate_data();
143+
144+
facp_addr = (uint8_t *)get_acpi_tbl(ACPI_SIG_FADT);
145+
146+
if (facp_addr != NULL) {
147+
get_acpi_dt_gas(facp_addr, OFFSET_PM1A_EVT, &pm1a_evt);
148+
get_acpi_dt_gas(facp_addr, OFFSET_PM1A_CNT, &pm1a_cnt);
149+
(void)memcpy_s((void *)&sx_data->pm1a_evt, sizeof(struct acpi_generic_address),
150+
(const void *)&pm1a_evt, sizeof(struct acpi_generic_address));
151+
(void)memcpy_s((void *)&sx_data->pm1a_cnt, sizeof(struct acpi_generic_address),
152+
(const void *)&pm1a_cnt, sizeof(struct acpi_generic_address));
153+
154+
facs_addr = (uint8_t *)get_facs_table(facp_addr);
155+
if (facs_addr != NULL) {
156+
sx_data->wake_vector_32 = (uint32_t *)(facs_addr + OFFSET_WAKE_VECTOR_32);
157+
sx_data->wake_vector_64 = (uint64_t *)(facs_addr + OFFSET_WAKE_VECTOR_64);
158+
}
159+
}
160+
}
161+
#endif

hypervisor/boot/acpi.c renamed to hypervisor/boot/acpi_base.c

Lines changed: 0 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
#define ACPI_SIG_RSDP "RSD PTR " /* Root System Description Ptr */
4040
#define ACPI_OEM_ID_SIZE 6
4141
#define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */
42-
#define ACPI_SIG_FADT "FACP" /* Fixed ACPI Description Table */
4342
#define RSDP_CHECKSUM_LENGTH 20
4443
#define ACPI_NAME_SIZE 4U
4544
#define ACPI_MADT_TYPE_LOCAL_APIC 0U
@@ -320,126 +319,3 @@ uint16_t parse_madt_ioapic(struct ioapic_info *ioapic_id_array)
320319

321320
return ioapic_parse_madt(madt, ioapic_id_array);
322321
}
323-
324-
#ifndef CONFIG_CONSTANT_ACPI
325-
/* Per ACPI spec:
326-
* There are two fundamental types of ACPI tables:
327-
*
328-
* Tables that contain AML code produced from the ACPI Source Language (ASL).
329-
* These include the DSDT, any SSDTs, and sometimes OEM-specific tables (OEMx).
330-
*
331-
* Tables that contain simple data and no AML byte code. These types of tables
332-
* are known as ACPI Data Tables. They include tables such as the FADT, MADT,
333-
* ECDT, SRAT, etc. -essentially any table other than a DSDT or SSDT.
334-
*
335-
* The second type of table, the ACPI Data Table, could be parsed here.
336-
*
337-
* When ACRN go FuSa, the platform ACPI data should be fixed. The MACRO of
338-
* CONFIG_CONSTANT_ACPI will be defined, then this code is not needed.
339-
*/
340-
341-
#define ACPI_SIG_FACS 0x53434146U /* "FACS" */
342-
343-
/* FACP field offsets */
344-
#define OFFSET_FACS_ADDR 36U
345-
#define OFFSET_FACS_X_ADDR 132U
346-
#define OFFSET_PM1A_EVT 148U
347-
#define OFFSET_PM1A_CNT 172U
348-
349-
/* FACS field offsets */
350-
#define OFFSET_FACS_SIGNATURE 0U
351-
#define OFFSET_FACS_LENGTH 4U
352-
#define OFFSET_WAKE_VECTOR_32 12U
353-
#define OFFSET_WAKE_VECTOR_64 24U
354-
355-
/* get a dword value from given table and its offset */
356-
static inline uint32_t get_acpi_dt_dword(const uint8_t *dt_addr, uint32_t dt_offset)
357-
{
358-
return *(uint32_t *)(dt_addr + dt_offset);
359-
}
360-
361-
/* get a qword value from given table and its offset */
362-
static inline uint64_t get_acpi_dt_qword(const uint8_t *dt_addr, uint32_t dt_offset)
363-
{
364-
return *(uint64_t *)(dt_addr + dt_offset);
365-
}
366-
367-
struct packed_gas {
368-
uint8_t space_id;
369-
uint8_t bit_width;
370-
uint8_t bit_offset;
371-
uint8_t access_size;
372-
uint64_t address;
373-
} __attribute__((packed));
374-
375-
/* get a GAS struct from given table and its offset.
376-
* ACPI table stores packed gas, but it is not guaranteed that
377-
* struct acpi_generic_address is packed, so do not use memcpy in function.
378-
* @pre dt_addr != NULL && gas != NULL
379-
*/
380-
static inline void get_acpi_dt_gas(const uint8_t *dt_addr, uint32_t dt_offset, struct acpi_generic_address *gas)
381-
{
382-
struct packed_gas *dt_gas = (struct packed_gas *)(dt_addr + dt_offset);
383-
384-
gas->space_id = dt_gas->space_id;
385-
gas->bit_width = dt_gas->bit_width;
386-
gas->bit_offset = dt_gas->bit_offset;
387-
gas->access_size = dt_gas->access_size;
388-
gas->address = dt_gas->address;
389-
}
390-
391-
/* @pre facp_addr != NULL */
392-
static void *get_facs_table(const uint8_t *facp_addr)
393-
{
394-
uint8_t *facs_addr, *facs_x_addr;
395-
uint32_t signature, length;
396-
397-
facs_addr = (uint8_t *)(uint64_t)get_acpi_dt_dword(facp_addr, OFFSET_FACS_ADDR);
398-
399-
facs_x_addr = (uint8_t *)get_acpi_dt_qword(facp_addr, OFFSET_FACS_X_ADDR);
400-
401-
if (facs_x_addr != NULL) {
402-
facs_addr = facs_x_addr;
403-
}
404-
405-
if (facs_addr != NULL) {
406-
signature = get_acpi_dt_dword(facs_addr, OFFSET_FACS_SIGNATURE);
407-
408-
if (signature != ACPI_SIG_FACS) {
409-
facs_addr = NULL;
410-
} else {
411-
length = get_acpi_dt_dword(facs_addr, OFFSET_FACS_LENGTH);
412-
413-
if (length < 64U) {
414-
facs_addr = NULL;
415-
}
416-
}
417-
}
418-
return (void *)facs_addr;
419-
}
420-
421-
/* put all ACPI fix up code here */
422-
void acpi_fixup(void)
423-
{
424-
uint8_t *facp_addr, *facs_addr;
425-
struct acpi_generic_address pm1a_cnt, pm1a_evt;
426-
struct pm_s_state_data *sx_data = get_host_sstate_data();
427-
428-
facp_addr = (uint8_t *)get_acpi_tbl(ACPI_SIG_FADT);
429-
430-
if (facp_addr != NULL) {
431-
get_acpi_dt_gas(facp_addr, OFFSET_PM1A_EVT, &pm1a_evt);
432-
get_acpi_dt_gas(facp_addr, OFFSET_PM1A_CNT, &pm1a_cnt);
433-
(void)memcpy_s((void *)&sx_data->pm1a_evt, sizeof(struct acpi_generic_address),
434-
(const void *)&pm1a_evt, sizeof(struct acpi_generic_address));
435-
(void)memcpy_s((void *)&sx_data->pm1a_cnt, sizeof(struct acpi_generic_address),
436-
(const void *)&pm1a_cnt, sizeof(struct acpi_generic_address));
437-
438-
facs_addr = (uint8_t *)get_facs_table(facp_addr);
439-
if (facs_addr != NULL) {
440-
sx_data->wake_vector_32 = (uint32_t *)(facs_addr + OFFSET_WAKE_VECTOR_32);
441-
sx_data->wake_vector_64 = (uint64_t *)(facs_addr + OFFSET_WAKE_VECTOR_64);
442-
}
443-
}
444-
}
445-
#endif

0 commit comments

Comments
 (0)