mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 21:38:32 +08:00
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:
commit
02fedf1466
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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]",
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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];
|
||||
|
@ -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,
|
||||
|
@ -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__ */
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user