[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 25/88] ppc/pnv: Add HIOMAP commands
From: |
David Gibson |
Subject: |
[PULL 25/88] ppc/pnv: Add HIOMAP commands |
Date: |
Tue, 17 Dec 2019 15:42:19 +1100 |
From: Cédric Le Goater <address@hidden>
This activates HIOMAP support on the QEMU PowerNV machine. The PnvPnor
model is used to access the flash contents. The model simply maps the
contents at a fix offset and enables or disables the mapping.
HIOMAP Protocol description :
https://github.com/openbmc/hiomapd/blob/master/Documentation/protocol.md
Reviewed-by: Joel Stanley <address@hidden>
Signed-off-by: Cédric Le Goater <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: David Gibson <address@hidden>
---
hw/ppc/pnv.c | 1 +
hw/ppc/pnv_bmc.c | 102 ++++++++++++++++++++++++++++++++++++++
hw/ppc/pnv_lpc.c | 13 +++++
include/hw/ppc/pnv.h | 1 +
include/hw/ppc/pnv_pnor.h | 5 ++
5 files changed, 122 insertions(+)
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index a2a8b97330..c3ac0d6d5b 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -569,6 +569,7 @@ static void pnv_reset(MachineState *machine)
obj = object_resolve_path_type("", "ipmi-bmc-sim", NULL);
if (obj) {
pnv->bmc = IPMI_BMC(obj);
+ pnv_bmc_hiomap(pnv->bmc);
}
fdt = pnv_dt_create(machine);
diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
index dc5e918cb7..aa5c89586c 100644
--- a/hw/ppc/pnv_bmc.c
+++ b/hw/ppc/pnv_bmc.c
@@ -114,3 +114,105 @@ void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt)
sdr->sensor_type)));
}
}
+
+/*
+ * HIOMAP protocol handler
+ */
+#define HIOMAP_C_RESET 1
+#define HIOMAP_C_GET_INFO 2
+#define HIOMAP_C_GET_FLASH_INFO 3
+#define HIOMAP_C_CREATE_READ_WINDOW 4
+#define HIOMAP_C_CLOSE_WINDOW 5
+#define HIOMAP_C_CREATE_WRITE_WINDOW 6
+#define HIOMAP_C_MARK_DIRTY 7
+#define HIOMAP_C_FLUSH 8
+#define HIOMAP_C_ACK 9
+#define HIOMAP_C_ERASE 10
+#define HIOMAP_C_DEVICE_NAME 11
+#define HIOMAP_C_LOCK 12
+
+#define BLOCK_SHIFT 12 /* 4K */
+
+static uint16_t bytes_to_blocks(uint32_t bytes)
+{
+ return bytes >> BLOCK_SHIFT;
+}
+
+static void hiomap_cmd(IPMIBmcSim *ibs, uint8_t *cmd, unsigned int cmd_len,
+ RspBuffer *rsp)
+{
+ PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
+ PnvPnor *pnor = pnv->pnor;
+ uint32_t pnor_size = pnor->size;
+ uint32_t pnor_addr = PNOR_SPI_OFFSET;
+ bool readonly = false;
+
+ rsp_buffer_push(rsp, cmd[2]);
+ rsp_buffer_push(rsp, cmd[3]);
+
+ switch (cmd[2]) {
+ case HIOMAP_C_MARK_DIRTY:
+ case HIOMAP_C_FLUSH:
+ case HIOMAP_C_ERASE:
+ case HIOMAP_C_ACK:
+ break;
+
+ case HIOMAP_C_GET_INFO:
+ rsp_buffer_push(rsp, 2); /* Version 2 */
+ rsp_buffer_push(rsp, BLOCK_SHIFT); /* block size */
+ rsp_buffer_push(rsp, 0); /* Timeout */
+ rsp_buffer_push(rsp, 0); /* Timeout */
+ break;
+
+ case HIOMAP_C_GET_FLASH_INFO:
+ rsp_buffer_push(rsp, bytes_to_blocks(pnor_size) & 0xFF);
+ rsp_buffer_push(rsp, bytes_to_blocks(pnor_size) >> 8);
+ rsp_buffer_push(rsp, 0x01); /* erase size */
+ rsp_buffer_push(rsp, 0x00); /* erase size */
+ break;
+
+ case HIOMAP_C_CREATE_READ_WINDOW:
+ readonly = true;
+ /* Fall through */
+
+ case HIOMAP_C_CREATE_WRITE_WINDOW:
+ memory_region_set_readonly(&pnor->mmio, readonly);
+ memory_region_set_enabled(&pnor->mmio, true);
+
+ rsp_buffer_push(rsp, bytes_to_blocks(pnor_addr) & 0xFF);
+ rsp_buffer_push(rsp, bytes_to_blocks(pnor_addr) >> 8);
+ rsp_buffer_push(rsp, bytes_to_blocks(pnor_size) & 0xFF);
+ rsp_buffer_push(rsp, bytes_to_blocks(pnor_size) >> 8);
+ rsp_buffer_push(rsp, 0x00); /* offset */
+ rsp_buffer_push(rsp, 0x00); /* offset */
+ break;
+
+ case HIOMAP_C_CLOSE_WINDOW:
+ memory_region_set_enabled(&pnor->mmio, false);
+ break;
+
+ case HIOMAP_C_DEVICE_NAME:
+ case HIOMAP_C_RESET:
+ case HIOMAP_C_LOCK:
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "HIOMAP: unknow command %02X\n",
cmd[2]);
+ break;
+ }
+}
+
+#define HIOMAP 0x5a
+
+static const IPMICmdHandler hiomap_cmds[] = {
+ [HIOMAP] = { hiomap_cmd, 3 },
+};
+
+static const IPMINetfn hiomap_netfn = {
+ .cmd_nums = ARRAY_SIZE(hiomap_cmds),
+ .cmd_handlers = hiomap_cmds
+};
+
+int pnv_bmc_hiomap(IPMIBmc *bmc)
+{
+ return ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(bmc),
+ IPMI_NETFN_OEM, &hiomap_netfn);
+}
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index c5a85c38c7..dd5374c838 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -810,6 +810,7 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool
use_cpld, Error **errp)
ISABus *isa_bus;
qemu_irq *irqs;
qemu_irq_handler handler;
+ PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
/* let isa_bus_new() create its own bridge on SysBus otherwise
* devices speficied on the command line won't find the bus and
@@ -834,5 +835,17 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool
use_cpld, Error **errp)
irqs = qemu_allocate_irqs(handler, lpc, ISA_NUM_IRQS);
isa_bus_irqs(isa_bus, irqs);
+
+ /*
+ * TODO: Map PNOR on the LPC FW address space on demand ?
+ */
+ memory_region_add_subregion(&lpc->isa_fw, PNOR_SPI_OFFSET,
+ &pnv->pnor->mmio);
+ /*
+ * Start disabled. The HIOMAP protocol will activate the mapping
+ * with HIOMAP_C_CREATE_WRITE_WINDOW
+ */
+ memory_region_set_enabled(&pnv->pnor->mmio, false);
+
return isa_bus;
}
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 5ecd3ba6ed..07c56c05ad 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -198,6 +198,7 @@ static inline bool pnv_is_power9(PnvMachineState *pnv)
*/
void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt);
void pnv_bmc_powerdown(IPMIBmc *bmc);
+int pnv_bmc_hiomap(IPMIBmc *bmc);
/*
* POWER8 MMIO base addresses
diff --git a/include/hw/ppc/pnv_pnor.h b/include/hw/ppc/pnv_pnor.h
index dec811695c..c3dd28643c 100644
--- a/include/hw/ppc/pnv_pnor.h
+++ b/include/hw/ppc/pnv_pnor.h
@@ -9,6 +9,11 @@
#ifndef _PPC_PNV_PNOR_H
#define _PPC_PNV_PNOR_H
+/*
+ * PNOR offset on the LPC FW address space
+ */
+#define PNOR_SPI_OFFSET 0x0c000000UL
+
#define TYPE_PNV_PNOR "pnv-pnor"
#define PNV_PNOR(obj) OBJECT_CHECK(PnvPnor, (obj), TYPE_PNV_PNOR)
--
2.23.0
- [PULL 23/88] ppc/xive: Check V bit in TM_PULL_POOL_CTX, (continued)
- [PULL 23/88] ppc/xive: Check V bit in TM_PULL_POOL_CTX, David Gibson, 2019/12/16
- [PULL 13/88] xics: Link ICP_PROP_XICS property to ICPState::xics pointer, David Gibson, 2019/12/16
- [PULL 17/88] ppc/xive: Record the IPB in the associated NVT, David Gibson, 2019/12/16
- [PULL 27/88] ppc/xive: Introduce a XivePresenter interface, David Gibson, 2019/12/16
- [PULL 26/88] ppc/pnv: Create BMC devices at machine init, David Gibson, 2019/12/16
- [PULL 28/88] ppc/xive: Implement the XivePresenter interface, David Gibson, 2019/12/16
- [PULL 21/88] ppc/pnv: Quiesce some XIVE errors, David Gibson, 2019/12/16
- [PULL 22/88] ppc/xive: Introduce OS CAM line helpers, David Gibson, 2019/12/16
- [PULL 24/88] ipmi: Add support to customize OEM functions, David Gibson, 2019/12/16
- [PULL 36/88] ppc/spapr: Implement the XiveFabric interface, David Gibson, 2019/12/16
- [PULL 25/88] ppc/pnv: Add HIOMAP commands,
David Gibson <=
- [PULL 34/88] ppc/xive: Introduce a XiveFabric interface, David Gibson, 2019/12/16
- [PULL 30/88] ppc/pnv: Loop on the threads of the chip to find a matching NVT, David Gibson, 2019/12/16
- [PULL 35/88] ppc/pnv: Implement the XiveFabric interface, David Gibson, 2019/12/16
- [PULL 41/88] spapr/xics: Configure number of servers in KVM, David Gibson, 2019/12/16
- [PULL 32/88] ppc/pnv: Introduce a pnv_xive_is_cpu_enabled() helper, David Gibson, 2019/12/16
- [PULL 33/88] ppc/pnv: Fix TIMA indirect access, David Gibson, 2019/12/16
- [PULL 37/88] ppc/xive: Use the XiveFabric and XivePresenter interfaces, David Gibson, 2019/12/16
- [PULL 29/88] ppc/pnv: Instantiate cores separately, David Gibson, 2019/12/16
- [PULL 31/88] ppc: Introduce a ppc_cpu_pir() helper, David Gibson, 2019/12/16
- [PULL 44/88] ppc/xive: Move the TIMA operations to the controller model, David Gibson, 2019/12/16