mirror of https://github.com/xemu-project/xemu.git
ppc/pnv: Add HIOMAP commands
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 <joel@jms.id.au> Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-Id: <20191028070027.22752-3-clg@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
ed8da05cdb
commit
ca661fae81
|
@ -569,6 +569,7 @@ static void pnv_reset(MachineState *machine)
|
||||||
obj = object_resolve_path_type("", "ipmi-bmc-sim", NULL);
|
obj = object_resolve_path_type("", "ipmi-bmc-sim", NULL);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
pnv->bmc = IPMI_BMC(obj);
|
pnv->bmc = IPMI_BMC(obj);
|
||||||
|
pnv_bmc_hiomap(pnv->bmc);
|
||||||
}
|
}
|
||||||
|
|
||||||
fdt = pnv_dt_create(machine);
|
fdt = pnv_dt_create(machine);
|
||||||
|
|
102
hw/ppc/pnv_bmc.c
102
hw/ppc/pnv_bmc.c
|
@ -114,3 +114,105 @@ void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt)
|
||||||
sdr->sensor_type)));
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -810,6 +810,7 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp)
|
||||||
ISABus *isa_bus;
|
ISABus *isa_bus;
|
||||||
qemu_irq *irqs;
|
qemu_irq *irqs;
|
||||||
qemu_irq_handler handler;
|
qemu_irq_handler handler;
|
||||||
|
PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
|
||||||
|
|
||||||
/* let isa_bus_new() create its own bridge on SysBus otherwise
|
/* let isa_bus_new() create its own bridge on SysBus otherwise
|
||||||
* devices speficied on the command line won't find the bus and
|
* 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);
|
irqs = qemu_allocate_irqs(handler, lpc, ISA_NUM_IRQS);
|
||||||
|
|
||||||
isa_bus_irqs(isa_bus, 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;
|
return isa_bus;
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,6 +198,7 @@ static inline bool pnv_is_power9(PnvMachineState *pnv)
|
||||||
*/
|
*/
|
||||||
void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt);
|
void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt);
|
||||||
void pnv_bmc_powerdown(IPMIBmc *bmc);
|
void pnv_bmc_powerdown(IPMIBmc *bmc);
|
||||||
|
int pnv_bmc_hiomap(IPMIBmc *bmc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* POWER8 MMIO base addresses
|
* POWER8 MMIO base addresses
|
||||||
|
|
|
@ -9,6 +9,11 @@
|
||||||
#ifndef _PPC_PNV_PNOR_H
|
#ifndef _PPC_PNV_PNOR_H
|
||||||
#define _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 TYPE_PNV_PNOR "pnv-pnor"
|
||||||
#define PNV_PNOR(obj) OBJECT_CHECK(PnvPnor, (obj), TYPE_PNV_PNOR)
|
#define PNV_PNOR(obj) OBJECT_CHECK(PnvPnor, (obj), TYPE_PNV_PNOR)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue