Merge branch 'for-6.2/cxl-xor' into for-6.2/cxl

Pick up support for "XOR" interleave math when parsing ACPI CFMWS window
structures. Fix up conflicts with the RCH emulation already pending in
cxl/next.
This commit is contained in:
Dan Williams 2022-12-05 12:32:11 -08:00
commit 02fedf1466
18 changed files with 542 additions and 32 deletions

View file

@ -142,6 +142,9 @@ static acpi_status acpi_ev_fixed_event_initialize(void)
status =
acpi_write_bit_register(acpi_gbl_fixed_event_info
[i].enable_register_id,
(i ==
ACPI_EVENT_PCIE_WAKE) ?
ACPI_ENABLE_EVENT :
ACPI_DISABLE_EVENT);
if (ACPI_FAILURE(status)) {
return (status);
@ -185,6 +188,11 @@ u32 acpi_ev_fixed_event_detect(void)
return (int_status);
}
if (fixed_enable & ACPI_BITMASK_PCIEXP_WAKE_DISABLE)
fixed_enable &= ~ACPI_BITMASK_PCIEXP_WAKE_DISABLE;
else
fixed_enable |= ACPI_BITMASK_PCIEXP_WAKE_DISABLE;
ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
"Fixed Event Block: Enable %08X Status %08X\n",
fixed_enable, fixed_status));
@ -250,6 +258,9 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event)
if (!acpi_gbl_fixed_event_handlers[event].handler) {
(void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
enable_register_id,
(event ==
ACPI_EVENT_PCIE_WAKE) ?
ACPI_ENABLE_EVENT :
ACPI_DISABLE_EVENT);
ACPI_ERROR((AE_INFO,

View file

@ -172,6 +172,15 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
ctx->subspace_id = (u8)region_obj->region.address;
}
if (region_obj->region.space_id ==
ACPI_ADR_SPACE_FIXED_HARDWARE) {
struct acpi_ffh_info *ctx =
handler_desc->address_space.context;
ctx->length = region_obj->region.length;
ctx->offset = region_obj->region.address;
}
/*
* We must exit the interpreter because the region setup will
* potentially execute control methods (for example, the _REG method

View file

@ -295,8 +295,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
target));
}
if (target->common.type != ACPI_TYPE_INTEGER) {
ACPI_EXCEPTION((AE_INFO, AE_TYPE,
"Type not integer: %X\n", target->common.type));
ACPI_ERROR((AE_INFO, "Type not integer: %X",
target->common.type));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}

View file

@ -141,7 +141,9 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
|| obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_IPMI
|| obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_PLATFORM_RT)) {
ACPI_ADR_SPACE_PLATFORM_RT
|| obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_FIXED_HARDWARE)) {
/* SMBus, GSBus, IPMI serial */
@ -305,7 +307,9 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
|| obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_IPMI
|| obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_PLATFORM_RT)) {
ACPI_ADR_SPACE_PLATFORM_RT
|| obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_FIXED_HARDWARE)) {
/* SMBus, GSBus, IPMI serial */

View file

@ -323,6 +323,12 @@ acpi_ex_write_serial_bus(union acpi_operand_object *source_desc,
function = ACPI_WRITE;
break;
case ACPI_ADR_SPACE_FIXED_HARDWARE:
buffer_length = ACPI_FFH_INPUT_BUFFER_SIZE;
function = ACPI_WRITE;
break;
default:
return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
}

View file

@ -311,6 +311,20 @@ acpi_status acpi_hw_legacy_wake(u8 sleep_state)
[ACPI_EVENT_SLEEP_BUTTON].
status_register_id, ACPI_CLEAR_STATUS);
/* Enable pcie wake event if support */
if ((acpi_gbl_FADT.flags & ACPI_FADT_PCI_EXPRESS_WAKE)) {
(void)
acpi_write_bit_register(acpi_gbl_fixed_event_info
[ACPI_EVENT_PCIE_WAKE].
enable_register_id,
ACPI_DISABLE_EVENT);
(void)
acpi_write_bit_register(acpi_gbl_fixed_event_info
[ACPI_EVENT_PCIE_WAKE].
status_register_id,
ACPI_CLEAR_STATUS);
}
acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING);
return_ACPI_STATUS(status);
}

View file

@ -114,6 +114,7 @@ acpi_find_root_pointer(acpi_physical_address *table_address)
u8 *table_ptr;
u8 *mem_rover;
u32 physical_address;
u32 ebda_window_size;
ACPI_FUNCTION_TRACE(acpi_find_root_pointer);
@ -139,26 +140,37 @@ acpi_find_root_pointer(acpi_physical_address *table_address)
/* EBDA present? */
if (physical_address > 0x400) {
/*
* Check that the EBDA pointer from memory is sane and does not point
* above valid low memory
*/
if (physical_address > 0x400 && physical_address < 0xA0000) {
/*
* 1b) Search EBDA paragraphs (EBDA is required to be a
* minimum of 1K length)
* Calculate the scan window size
* The EBDA is not guaranteed to be larger than a ki_b and in case
* that it is smaller, the scanning function would leave the low
* memory and continue to the VGA range.
*/
ebda_window_size = ACPI_MIN(ACPI_EBDA_WINDOW_SIZE,
0xA0000 - physical_address);
/*
* 1b) Search EBDA paragraphs
*/
table_ptr = acpi_os_map_memory((acpi_physical_address)
physical_address,
ACPI_EBDA_WINDOW_SIZE);
ebda_window_size);
if (!table_ptr) {
ACPI_ERROR((AE_INFO,
"Could not map memory at 0x%8.8X for length %u",
physical_address, ACPI_EBDA_WINDOW_SIZE));
physical_address, ebda_window_size));
return_ACPI_STATUS(AE_NO_MEMORY);
}
mem_rover =
acpi_tb_scan_memory_for_rsdp(table_ptr,
ACPI_EBDA_WINDOW_SIZE);
acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE);
acpi_tb_scan_memory_for_rsdp(table_ptr, ebda_window_size);
acpi_os_unmap_memory(table_ptr, ebda_window_size);
if (mem_rover) {

View file

@ -186,6 +186,10 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] =
ACPI_BITREG_RT_CLOCK_ENABLE,
ACPI_BITMASK_RT_CLOCK_STATUS,
ACPI_BITMASK_RT_CLOCK_ENABLE},
/* ACPI_EVENT_PCIE_WAKE */ {ACPI_BITREG_PCIEXP_WAKE_STATUS,
ACPI_BITREG_PCIEXP_WAKE_DISABLE,
ACPI_BITMASK_PCIEXP_WAKE_STATUS,
ACPI_BITMASK_PCIEXP_WAKE_DISABLE},
};
#endif /* !ACPI_REDUCED_HARDWARE */

View file

@ -145,7 +145,7 @@ void acpi_ut_repair_name(char *name)
return;
}
ACPI_COPY_NAMESEG(&original_name, name);
ACPI_COPY_NAMESEG(&original_name, &name[0]);
/* Check each character in the name */
@ -156,10 +156,10 @@ void acpi_ut_repair_name(char *name)
/*
* Replace a bad character with something printable, yet technically
* still invalid. This prevents any collisions with existing "good"
* "odd". This prevents any collisions with existing "good"
* names in the namespace.
*/
name[i] = '*';
name[i] = '_';
found_bad_char = TRUE;
}
@ -169,8 +169,8 @@ void acpi_ut_repair_name(char *name)
if (!acpi_gbl_enable_interpreter_slack) {
ACPI_WARNING((AE_INFO,
"Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
original_name, name));
"Invalid character(s) in name (0x%.8X) %p, repaired: [%4.4s]",
original_name, name, &name[0]));
} else {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",

View file

@ -6,11 +6,120 @@
#include <linux/kernel.h>
#include <linux/acpi.h>
#include <linux/pci.h>
#include <asm/div64.h>
#include "cxlpci.h"
#include "cxl.h"
#define CXL_RCRB_SIZE SZ_8K
struct cxl_cxims_data {
int nr_maps;
u64 xormaps[];
};
/*
* Find a targets entry (n) in the host bridge interleave list.
* CXL Specfication 3.0 Table 9-22
*/
static int cxl_xor_calc_n(u64 hpa, struct cxl_cxims_data *cximsd, int iw,
int ig)
{
int i = 0, n = 0;
u8 eiw;
/* IW: 2,4,6,8,12,16 begin building 'n' using xormaps */
if (iw != 3) {
for (i = 0; i < cximsd->nr_maps; i++)
n |= (hweight64(hpa & cximsd->xormaps[i]) & 1) << i;
}
/* IW: 3,6,12 add a modulo calculation to 'n' */
if (!is_power_of_2(iw)) {
if (ways_to_cxl(iw, &eiw))
return -1;
hpa &= GENMASK_ULL(51, eiw + ig);
n |= do_div(hpa, 3) << i;
}
return n;
}
static struct cxl_dport *cxl_hb_xor(struct cxl_root_decoder *cxlrd, int pos)
{
struct cxl_cxims_data *cximsd = cxlrd->platform_data;
struct cxl_switch_decoder *cxlsd = &cxlrd->cxlsd;
struct cxl_decoder *cxld = &cxlsd->cxld;
int ig = cxld->interleave_granularity;
int iw = cxld->interleave_ways;
int n = 0;
u64 hpa;
if (dev_WARN_ONCE(&cxld->dev,
cxld->interleave_ways != cxlsd->nr_targets,
"misconfigured root decoder\n"))
return NULL;
hpa = cxlrd->res->start + pos * ig;
/* Entry (n) is 0 for no interleave (iw == 1) */
if (iw != 1)
n = cxl_xor_calc_n(hpa, cximsd, iw, ig);
if (n < 0)
return NULL;
return cxlrd->cxlsd.target[n];
}
struct cxl_cxims_context {
struct device *dev;
struct cxl_root_decoder *cxlrd;
};
static int cxl_parse_cxims(union acpi_subtable_headers *header, void *arg,
const unsigned long end)
{
struct acpi_cedt_cxims *cxims = (struct acpi_cedt_cxims *)header;
struct cxl_cxims_context *ctx = arg;
struct cxl_root_decoder *cxlrd = ctx->cxlrd;
struct cxl_decoder *cxld = &cxlrd->cxlsd.cxld;
struct device *dev = ctx->dev;
struct cxl_cxims_data *cximsd;
unsigned int hbig, nr_maps;
int rc;
rc = cxl_to_granularity(cxims->hbig, &hbig);
if (rc)
return rc;
/* Does this CXIMS entry apply to the given CXL Window? */
if (hbig != cxld->interleave_granularity)
return 0;
/* IW 1,3 do not use xormaps and skip this parsing entirely */
if (is_power_of_2(cxld->interleave_ways))
/* 2, 4, 8, 16 way */
nr_maps = ilog2(cxld->interleave_ways);
else
/* 6, 12 way */
nr_maps = ilog2(cxld->interleave_ways / 3);
if (cxims->nr_xormaps < nr_maps) {
dev_dbg(dev, "CXIMS nr_xormaps[%d] expected[%d]\n",
cxims->nr_xormaps, nr_maps);
return -ENXIO;
}
cximsd = devm_kzalloc(dev, struct_size(cximsd, xormaps, nr_maps),
GFP_KERNEL);
if (!cximsd)
return -ENOMEM;
memcpy(cximsd->xormaps, cxims->xormap_list,
nr_maps * sizeof(*cximsd->xormaps));
cximsd->nr_maps = nr_maps;
cxlrd->platform_data = cximsd;
return 0;
}
static unsigned long cfmws_to_decoder_flags(int restrictions)
{
unsigned long flags = CXL_DECODER_F_ENABLE;
@ -35,8 +144,10 @@ static int cxl_acpi_cfmws_verify(struct device *dev,
int rc, expected_len;
unsigned int ways;
if (cfmws->interleave_arithmetic != ACPI_CEDT_CFMWS_ARITHMETIC_MODULO) {
dev_err(dev, "CFMWS Unsupported Interleave Arithmetic\n");
if (cfmws->interleave_arithmetic != ACPI_CEDT_CFMWS_ARITHMETIC_MODULO &&
cfmws->interleave_arithmetic != ACPI_CEDT_CFMWS_ARITHMETIC_XOR) {
dev_err(dev, "CFMWS Unknown Interleave Arithmetic: %d\n",
cfmws->interleave_arithmetic);
return -EINVAL;
}
@ -90,9 +201,11 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,
struct cxl_cfmws_context *ctx = arg;
struct cxl_port *root_port = ctx->root_port;
struct resource *cxl_res = ctx->cxl_res;
struct cxl_cxims_context cxims_ctx;
struct cxl_root_decoder *cxlrd;
struct device *dev = ctx->dev;
struct acpi_cedt_cfmws *cfmws;
cxl_calc_hb_fn cxl_calc_hb;
struct cxl_decoder *cxld;
unsigned int ways, i, ig;
struct resource *res;
@ -134,7 +247,12 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,
if (rc)
goto err_insert;
cxlrd = cxl_root_decoder_alloc(root_port, ways);
if (cfmws->interleave_arithmetic == ACPI_CEDT_CFMWS_ARITHMETIC_MODULO)
cxl_calc_hb = cxl_hb_modulo;
else
cxl_calc_hb = cxl_hb_xor;
cxlrd = cxl_root_decoder_alloc(root_port, ways, cxl_calc_hb);
if (IS_ERR(cxlrd))
return 0;
@ -154,7 +272,20 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,
ig = CXL_DECODER_MIN_GRANULARITY;
cxld->interleave_granularity = ig;
if (cfmws->interleave_arithmetic == ACPI_CEDT_CFMWS_ARITHMETIC_XOR) {
if (ways != 1 && ways != 3) {
cxims_ctx = (struct cxl_cxims_context) {
.dev = dev,
.cxlrd = cxlrd,
};
rc = acpi_table_parse_cedt(ACPI_CEDT_TYPE_CXIMS,
cxl_parse_cxims, &cxims_ctx);
if (rc < 0)
goto err_xormap;
}
}
rc = cxl_decoder_add(cxld, target_map);
err_xormap:
if (rc)
put_device(&cxld->dev);
else

View file

@ -1484,7 +1484,7 @@ static int decoder_populate_targets(struct cxl_switch_decoder *cxlsd,
return rc;
}
static struct cxl_dport *cxl_hb_modulo(struct cxl_root_decoder *cxlrd, int pos)
struct cxl_dport *cxl_hb_modulo(struct cxl_root_decoder *cxlrd, int pos)
{
struct cxl_switch_decoder *cxlsd = &cxlrd->cxlsd;
struct cxl_decoder *cxld = &cxlsd->cxld;
@ -1497,6 +1497,7 @@ static struct cxl_dport *cxl_hb_modulo(struct cxl_root_decoder *cxlrd, int pos)
return cxlrd->cxlsd.target[pos % iw];
}
EXPORT_SYMBOL_NS_GPL(cxl_hb_modulo, CXL);
static struct lock_class_key cxl_decoder_key;
@ -1558,6 +1559,7 @@ static int cxl_switch_decoder_init(struct cxl_port *port,
* cxl_root_decoder_alloc - Allocate a root level decoder
* @port: owning CXL root of this decoder
* @nr_targets: static number of downstream targets
* @calc_hb: which host bridge covers the n'th position by granularity
*
* Return: A new cxl decoder to be registered by cxl_decoder_add(). A
* 'CXL root' decoder is one that decodes from a top-level / static platform
@ -1565,7 +1567,8 @@ static int cxl_switch_decoder_init(struct cxl_port *port,
* topology.
*/
struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
unsigned int nr_targets)
unsigned int nr_targets,
cxl_calc_hb_fn calc_hb)
{
struct cxl_root_decoder *cxlrd;
struct cxl_switch_decoder *cxlsd;
@ -1587,7 +1590,7 @@ struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
return ERR_PTR(rc);
}
cxlrd->calc_hb = cxl_hb_modulo;
cxlrd->calc_hb = calc_hb;
cxld = &cxlsd->cxld;
cxld->dev.type = &cxl_decoder_root_type;

View file

@ -353,18 +353,23 @@ struct cxl_switch_decoder {
struct cxl_dport *target[];
};
struct cxl_root_decoder;
typedef struct cxl_dport *(*cxl_calc_hb_fn)(struct cxl_root_decoder *cxlrd,
int pos);
/**
* struct cxl_root_decoder - Static platform CXL address decoder
* @res: host / parent resource for region allocations
* @region_id: region id for next region provisioning event
* @calc_hb: which host bridge covers the n'th position by granularity
* @platform_data: platform specific configuration data
* @cxlsd: base cxl switch decoder
*/
struct cxl_root_decoder {
struct resource *res;
atomic_t region_id;
struct cxl_dport *(*calc_hb)(struct cxl_root_decoder *cxlrd, int pos);
cxl_calc_hb_fn calc_hb;
void *platform_data;
struct cxl_switch_decoder cxlsd;
};
@ -613,7 +618,9 @@ struct cxl_endpoint_decoder *to_cxl_endpoint_decoder(struct device *dev);
bool is_root_decoder(struct device *dev);
bool is_endpoint_decoder(struct device *dev);
struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
unsigned int nr_targets);
unsigned int nr_targets,
cxl_calc_hb_fn calc_hb);
struct cxl_dport *cxl_hb_modulo(struct cxl_root_decoder *cxlrd, int pos);
struct cxl_switch_decoder *cxl_switch_decoder_alloc(struct cxl_port *port,
unsigned int nr_targets);
int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map);

View file

@ -190,6 +190,8 @@
#define ACPI_PRM_INPUT_BUFFER_SIZE 26
#define ACPI_FFH_INPUT_BUFFER_SIZE 256
/* _sx_d and _sx_w control methods */
#define ACPI_NUM_sx_d_METHODS 4

View file

@ -329,7 +329,9 @@ struct acpi_cedt_header {
enum acpi_cedt_type {
ACPI_CEDT_TYPE_CHBS = 0,
ACPI_CEDT_TYPE_CFMWS = 1,
ACPI_CEDT_TYPE_RESERVED = 2,
ACPI_CEDT_TYPE_CXIMS = 2,
ACPI_CEDT_TYPE_RDPAS = 3,
ACPI_CEDT_TYPE_RESERVED = 4,
};
/* Values for version field above */
@ -380,6 +382,7 @@ struct acpi_cedt_cfmws_target_element {
/* Values for Interleave Arithmetic field above */
#define ACPI_CEDT_CFMWS_ARITHMETIC_MODULO (0)
#define ACPI_CEDT_CFMWS_ARITHMETIC_XOR (1)
/* Values for Restrictions field above */
@ -389,6 +392,36 @@ struct acpi_cedt_cfmws_target_element {
#define ACPI_CEDT_CFMWS_RESTRICT_PMEM (1<<3)
#define ACPI_CEDT_CFMWS_RESTRICT_FIXED (1<<4)
/* 2: CXL XOR Interleave Math Structure */
struct acpi_cedt_cxims {
struct acpi_cedt_header header;
u16 reserved1;
u8 hbig;
u8 nr_xormaps;
u64 xormap_list[];
};
/* 3: CXL RCEC Downstream Port Association Structure */
struct acpi_cedt_rdpas {
struct acpi_cedt_header header;
u8 reserved1;
u16 length;
u16 segment;
u16 bdf;
u8 protocol;
u64 address;
};
/* Masks for bdf field above */
#define ACPI_CEDT_RDPAS_BUS_MASK 0xff00
#define ACPI_CEDT_RDPAS_DEVICE_MASK 0x00f8
#define ACPI_CEDT_RDPAS_FUNCTION_MASK 0x0007
#define ACPI_CEDT_RDPAS_PROTOCOL_IO (0)
#define ACPI_CEDT_RDPAS_PROTOCOL_CACHEMEM (1)
/*******************************************************************************
*
* CPEP - Corrected Platform Error Polling table (ACPI 4.0)

View file

@ -27,6 +27,7 @@
#define ACPI_SIG_AGDI "AGDI" /* Arm Generic Diagnostic Dump and Reset Device Interface */
#define ACPI_SIG_APMT "APMT" /* Arm Performance Monitoring Unit table */
#define ACPI_SIG_BDAT "BDAT" /* BIOS Data ACPI Table */
#define ACPI_SIG_CCEL "CCEL" /* CC Event Log Table */
#define ACPI_SIG_IORT "IORT" /* IO Remapping Table */
#define ACPI_SIG_IVRS "IVRS" /* I/O Virtualization Reporting Structure */
#define ACPI_SIG_LPIT "LPIT" /* Low Power Idle Table */
@ -352,6 +353,23 @@ struct acpi_table_bdat {
struct acpi_generic_address gas;
};
/*******************************************************************************
*
* CCEL - CC-Event Log
* From: "Guest-Host-Communication Interface (GHCI) for Intel
* Trust Domain Extensions (Intel TDX)". Feb 2022
*
******************************************************************************/
struct acpi_table_ccel {
struct acpi_table_header header; /* Common ACPI table header */
u8 CCtype;
u8 Ccsub_type;
u16 reserved;
u64 log_area_minimum_length;
u64 log_area_start_address;
};
/*******************************************************************************
*
* IORT - IO Remapping Table
@ -865,7 +883,14 @@ enum acpi_madt_type {
ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR = 14,
ACPI_MADT_TYPE_GENERIC_TRANSLATOR = 15,
ACPI_MADT_TYPE_MULTIPROC_WAKEUP = 16,
ACPI_MADT_TYPE_RESERVED = 17, /* 17 to 0x7F are reserved */
ACPI_MADT_TYPE_CORE_PIC = 17,
ACPI_MADT_TYPE_LIO_PIC = 18,
ACPI_MADT_TYPE_HT_PIC = 19,
ACPI_MADT_TYPE_EIO_PIC = 20,
ACPI_MADT_TYPE_MSI_PIC = 21,
ACPI_MADT_TYPE_BIO_PIC = 22,
ACPI_MADT_TYPE_LPC_PIC = 23,
ACPI_MADT_TYPE_RESERVED = 24, /* 24 to 0x7F are reserved */
ACPI_MADT_TYPE_OEM_RESERVED = 0x80 /* 0x80 to 0xFF are reserved for OEM use */
};
@ -1096,7 +1121,135 @@ struct acpi_madt_multiproc_wakeup_mailbox {
#define ACPI_MP_WAKE_COMMAND_WAKEUP 1
/* 17: OEM data */
/* 17: CPU Core Interrupt Controller (ACPI 6.5) */
struct acpi_madt_core_pic {
struct acpi_subtable_header header;
u8 version;
u32 processor_id;
u32 core_id;
u32 flags;
};
/* Values for Version field above */
enum acpi_madt_core_pic_version {
ACPI_MADT_CORE_PIC_VERSION_NONE = 0,
ACPI_MADT_CORE_PIC_VERSION_V1 = 1,
ACPI_MADT_CORE_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
/* 18: Legacy I/O Interrupt Controller (ACPI 6.5) */
struct acpi_madt_lio_pic {
struct acpi_subtable_header header;
u8 version;
u64 address;
u16 size;
u8 cascade[2];
u32 cascade_map[2];
};
/* Values for Version field above */
enum acpi_madt_lio_pic_version {
ACPI_MADT_LIO_PIC_VERSION_NONE = 0,
ACPI_MADT_LIO_PIC_VERSION_V1 = 1,
ACPI_MADT_LIO_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
/* 19: HT Interrupt Controller (ACPI 6.5) */
struct acpi_madt_ht_pic {
struct acpi_subtable_header header;
u8 version;
u64 address;
u16 size;
u8 cascade[8];
};
/* Values for Version field above */
enum acpi_madt_ht_pic_version {
ACPI_MADT_HT_PIC_VERSION_NONE = 0,
ACPI_MADT_HT_PIC_VERSION_V1 = 1,
ACPI_MADT_HT_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
/* 20: Extend I/O Interrupt Controller (ACPI 6.5) */
struct acpi_madt_eio_pic {
struct acpi_subtable_header header;
u8 version;
u8 cascade;
u8 node;
u64 node_map;
};
/* Values for Version field above */
enum acpi_madt_eio_pic_version {
ACPI_MADT_EIO_PIC_VERSION_NONE = 0,
ACPI_MADT_EIO_PIC_VERSION_V1 = 1,
ACPI_MADT_EIO_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
/* 21: MSI Interrupt Controller (ACPI 6.5) */
struct acpi_madt_msi_pic {
struct acpi_subtable_header header;
u8 version;
u64 msg_address;
u32 start;
u32 count;
};
/* Values for Version field above */
enum acpi_madt_msi_pic_version {
ACPI_MADT_MSI_PIC_VERSION_NONE = 0,
ACPI_MADT_MSI_PIC_VERSION_V1 = 1,
ACPI_MADT_MSI_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
/* 22: Bridge I/O Interrupt Controller (ACPI 6.5) */
struct acpi_madt_bio_pic {
struct acpi_subtable_header header;
u8 version;
u64 address;
u16 size;
u16 id;
u16 gsi_base;
};
/* Values for Version field above */
enum acpi_madt_bio_pic_version {
ACPI_MADT_BIO_PIC_VERSION_NONE = 0,
ACPI_MADT_BIO_PIC_VERSION_V1 = 1,
ACPI_MADT_BIO_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
/* 23: LPC Interrupt Controller (ACPI 6.5) */
struct acpi_madt_lpc_pic {
struct acpi_subtable_header header;
u8 version;
u64 address;
u16 size;
u8 cascade;
};
/* Values for Version field above */
enum acpi_madt_lpc_pic_version {
ACPI_MADT_LPC_PIC_VERSION_NONE = 0,
ACPI_MADT_LPC_PIC_VERSION_V1 = 1,
ACPI_MADT_LPC_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
/* 80: OEM data */
struct acpi_madt_oem_data {
u8 oem_data[0];

View file

@ -723,7 +723,8 @@ typedef u32 acpi_event_type;
#define ACPI_EVENT_POWER_BUTTON 2
#define ACPI_EVENT_SLEEP_BUTTON 3
#define ACPI_EVENT_RTC 4
#define ACPI_EVENT_MAX 4
#define ACPI_EVENT_PCIE_WAKE 5
#define ACPI_EVENT_MAX 5
#define ACPI_NUM_FIXED_EVENTS ACPI_EVENT_MAX + 1
/*
@ -1115,6 +1116,13 @@ struct acpi_pcc_info {
u8 *internal_buffer;
};
/* Special Context data for FFH Opregion (ACPI 6.5) */
struct acpi_ffh_info {
u64 offset;
u64 length;
};
typedef
acpi_status (*acpi_adr_space_setup) (acpi_handle region_handle,
u32 function,

View file

@ -69,5 +69,6 @@
#define UUID_HIERARCHICAL_DATA_EXTENSION "dbb8e3e6-5886-4ba6-8795-1319f52a966b"
#define UUID_CORESIGHT_GRAPH "3ecbc8b6-1d0e-4fb3-8107-e627f805c6cd"
#define UUID_USB4_CAPABILITIES "23a0d13a-26ab-486c-9c5f-0ffa525a575a"
#define UUID_1ST_FUNCTION_ID "893f00a6-660c-494e-bcfd-3043f4fb67c0"
#define UUID_2ND_FUNCTION_ID "107ededd-d381-4fd7-8da9-08e9a6c79644"
#endif /* __ACUUID_H__ */

View file

@ -11,6 +11,8 @@
#include <cxlmem.h>
#include "mock.h"
static int interleave_arithmetic;
#define NR_CXL_HOST_BRIDGES 2
#define NR_CXL_SINGLE_HOST 1
#define NR_CXL_RCH 1
@ -135,6 +137,22 @@ static struct {
struct acpi_cedt_cfmws cfmws;
u32 target[1];
} cfmws5;
struct {
struct acpi_cedt_cfmws cfmws;
u32 target[1];
} cfmws6;
struct {
struct acpi_cedt_cfmws cfmws;
u32 target[2];
} cfmws7;
struct {
struct acpi_cedt_cfmws cfmws;
u32 target[4];
} cfmws8;
struct {
struct acpi_cedt_cxims cxims;
u64 xormap_list[2];
} cxims0;
} __packed mock_cedt = {
.cedt = {
.header = {
@ -265,6 +283,66 @@ static struct {
},
.target = { 3 },
},
/* .cfmws6,7,8 use ACPI_CEDT_CFMWS_ARITHMETIC_XOR */
.cfmws6 = {
.cfmws = {
.header = {
.type = ACPI_CEDT_TYPE_CFMWS,
.length = sizeof(mock_cedt.cfmws6),
},
.interleave_arithmetic = ACPI_CEDT_CFMWS_ARITHMETIC_XOR,
.interleave_ways = 0,
.granularity = 4,
.restrictions = ACPI_CEDT_CFMWS_RESTRICT_TYPE3 |
ACPI_CEDT_CFMWS_RESTRICT_PMEM,
.qtg_id = 0,
.window_size = SZ_256M * 8UL,
},
.target = { 0, },
},
.cfmws7 = {
.cfmws = {
.header = {
.type = ACPI_CEDT_TYPE_CFMWS,
.length = sizeof(mock_cedt.cfmws7),
},
.interleave_arithmetic = ACPI_CEDT_CFMWS_ARITHMETIC_XOR,
.interleave_ways = 1,
.granularity = 0,
.restrictions = ACPI_CEDT_CFMWS_RESTRICT_TYPE3 |
ACPI_CEDT_CFMWS_RESTRICT_PMEM,
.qtg_id = 1,
.window_size = SZ_256M * 8UL,
},
.target = { 0, 1, },
},
.cfmws8 = {
.cfmws = {
.header = {
.type = ACPI_CEDT_TYPE_CFMWS,
.length = sizeof(mock_cedt.cfmws8),
},
.interleave_arithmetic = ACPI_CEDT_CFMWS_ARITHMETIC_XOR,
.interleave_ways = 2,
.granularity = 0,
.restrictions = ACPI_CEDT_CFMWS_RESTRICT_TYPE3 |
ACPI_CEDT_CFMWS_RESTRICT_PMEM,
.qtg_id = 0,
.window_size = SZ_256M * 16UL,
},
.target = { 0, 1, 0, 1, },
},
.cxims0 = {
.cxims = {
.header = {
.type = ACPI_CEDT_TYPE_CXIMS,
.length = sizeof(mock_cedt.cxims0),
},
.hbig = 0,
.nr_xormaps = 2,
},
.xormap_list = { 0x404100, 0x808200, },
},
};
struct acpi_cedt_cfmws *mock_cfmws[] = {
@ -274,6 +352,21 @@ struct acpi_cedt_cfmws *mock_cfmws[] = {
[3] = &mock_cedt.cfmws3.cfmws,
[4] = &mock_cedt.cfmws4.cfmws,
[5] = &mock_cedt.cfmws5.cfmws,
/* Modulo Math above, XOR Math below */
[6] = &mock_cedt.cfmws6.cfmws,
[7] = &mock_cedt.cfmws7.cfmws,
[8] = &mock_cedt.cfmws8.cfmws,
};
static int cfmws_start;
static int cfmws_end;
#define CFMWS_MOD_ARRAY_START 0
#define CFMWS_MOD_ARRAY_END 5
#define CFMWS_XOR_ARRAY_START 6
#define CFMWS_XOR_ARRAY_END 8
struct acpi_cedt_cxims *mock_cxims[1] = {
[0] = &mock_cedt.cxims0.cxims,
};
struct cxl_mock_res {
@ -345,7 +438,7 @@ static int populate_cedt(void)
chbs->length = size;
}
for (i = 0; i < ARRAY_SIZE(mock_cfmws); i++) {
for (i = cfmws_start; i <= cfmws_end; i++) {
struct acpi_cedt_cfmws *window = mock_cfmws[i];
res = alloc_mock_res(window->window_size, SZ_256M);
@ -390,12 +483,19 @@ static int mock_acpi_table_parse_cedt(enum acpi_cedt_type id,
}
if (id == ACPI_CEDT_TYPE_CFMWS)
for (i = 0; i < ARRAY_SIZE(mock_cfmws); i++) {
for (i = cfmws_start; i <= cfmws_end; i++) {
h = (union acpi_subtable_headers *) mock_cfmws[i];
end = (unsigned long) h + mock_cfmws[i]->header.length;
handler_arg(h, arg, end);
}
if (id == ACPI_CEDT_TYPE_CXIMS)
for (i = 0; i < ARRAY_SIZE(mock_cxims); i++) {
h = (union acpi_subtable_headers *)mock_cxims[i];
end = (unsigned long)h + mock_cxims[i]->header.length;
handler_arg(h, arg, end);
}
return 0;
}
@ -1032,6 +1132,16 @@ static __init int cxl_test_init(void)
if (rc)
goto err_gen_pool_add;
if (interleave_arithmetic == 1) {
cfmws_start = CFMWS_XOR_ARRAY_START;
cfmws_end = CFMWS_XOR_ARRAY_END;
dev_dbg(NULL, "cxl_test loading xor math option\n");
} else {
cfmws_start = CFMWS_MOD_ARRAY_START;
cfmws_end = CFMWS_MOD_ARRAY_END;
dev_dbg(NULL, "cxl_test loading modulo math option\n");
}
rc = populate_cedt();
if (rc)
goto err_populate;
@ -1216,6 +1326,8 @@ static __exit void cxl_test_exit(void)
unregister_cxl_mock_ops(&cxl_mock_ops);
}
module_param(interleave_arithmetic, int, 0000);
MODULE_PARM_DESC(interleave_arithmetic, "Modulo:0, XOR:1");
module_init(cxl_test_init);
module_exit(cxl_test_exit);
MODULE_LICENSE("GPL v2");