|
@@ -32,6 +32,31 @@ static uint64_t cxl_cache_mem_read_reg(void *opaque, hwaddr offset,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void dumb_hdm_handler(CXLComponentState *cxl_cstate, hwaddr offset,
|
|
|
|
+ uint32_t value)
|
|
|
|
+{
|
|
|
|
+ ComponentRegisters *cregs = &cxl_cstate->crb;
|
|
|
|
+ uint32_t *cache_mem = cregs->cache_mem_registers;
|
|
|
|
+ bool should_commit = false;
|
|
|
|
+
|
|
|
|
+ switch (offset) {
|
|
|
|
+ case A_CXL_HDM_DECODER0_CTRL:
|
|
|
|
+ should_commit = FIELD_EX32(value, CXL_HDM_DECODER0_CTRL, COMMIT);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ memory_region_transaction_begin();
|
|
|
|
+ stl_le_p((uint8_t *)cache_mem + offset, value);
|
|
|
|
+ if (should_commit) {
|
|
|
|
+ ARRAY_FIELD_DP32(cache_mem, CXL_HDM_DECODER0_CTRL, COMMIT, 0);
|
|
|
|
+ ARRAY_FIELD_DP32(cache_mem, CXL_HDM_DECODER0_CTRL, ERR, 0);
|
|
|
|
+ ARRAY_FIELD_DP32(cache_mem, CXL_HDM_DECODER0_CTRL, COMMITTED, 1);
|
|
|
|
+ }
|
|
|
|
+ memory_region_transaction_commit();
|
|
|
|
+}
|
|
|
|
+
|
|
static void cxl_cache_mem_write_reg(void *opaque, hwaddr offset, uint64_t value,
|
|
static void cxl_cache_mem_write_reg(void *opaque, hwaddr offset, uint64_t value,
|
|
unsigned size)
|
|
unsigned size)
|
|
{
|
|
{
|
|
@@ -50,6 +75,12 @@ static void cxl_cache_mem_write_reg(void *opaque, hwaddr offset, uint64_t value,
|
|
value |= ~mask & cregs->cache_mem_registers[offset / sizeof(*cregs->cache_mem_registers)];
|
|
value |= ~mask & cregs->cache_mem_registers[offset / sizeof(*cregs->cache_mem_registers)];
|
|
if (cregs->special_ops && cregs->special_ops->write) {
|
|
if (cregs->special_ops && cregs->special_ops->write) {
|
|
cregs->special_ops->write(cxl_cstate, offset, value, size);
|
|
cregs->special_ops->write(cxl_cstate, offset, value, size);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (offset >= A_CXL_HDM_DECODER_CAPABILITY &&
|
|
|
|
+ offset <= A_CXL_HDM_DECODER0_TARGET_LIST_HI) {
|
|
|
|
+ dumb_hdm_handler(cxl_cstate, offset, value);
|
|
} else {
|
|
} else {
|
|
cregs->cache_mem_registers[offset / sizeof(*cregs->cache_mem_registers)] = value;
|
|
cregs->cache_mem_registers[offset / sizeof(*cregs->cache_mem_registers)] = value;
|
|
}
|
|
}
|