aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2021-03-04 22:10:24 +0000
committerMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2021-03-07 10:39:05 +0000
commiteb169c76d092b289a6a150b725e8fb2de990379b (patch)
treedab7f57fdbabc7a8afdfee73b24044ba8cfbaccd
parent84fbefedfecafba2b339d17c9133225467b90c2e (diff)
downloadqemu-eb169c76d092b289a6a150b725e8fb2de990379b.zip
qemu-eb169c76d092b289a6a150b725e8fb2de990379b.tar.gz
qemu-eb169c76d092b289a6a150b725e8fb2de990379b.tar.bz2
esp: QOMify the internal ESP device state
Make this new QOM device state a child device of both the sysbus-esp and esp-pci implementations. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-4-mark.cave-ayland@ilande.co.uk>
-rw-r--r--hw/scsi/esp-pci.c50
-rw-r--r--hw/scsi/esp.c47
-rw-r--r--include/hw/scsi/esp.h5
3 files changed, 82 insertions, 20 deletions
diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c
index 4d7c2ca..27a0d36 100644
--- a/hw/scsi/esp-pci.c
+++ b/hw/scsi/esp-pci.c
@@ -79,8 +79,10 @@ struct PCIESPState {
static void esp_pci_handle_idle(PCIESPState *pci, uint32_t val)
{
+ ESPState *s = ESP(&pci->esp);
+
trace_esp_pci_dma_idle(val);
- esp_dma_enable(&pci->esp, 0, 0);
+ esp_dma_enable(s, 0, 0);
}
static void esp_pci_handle_blast(PCIESPState *pci, uint32_t val)
@@ -91,14 +93,18 @@ static void esp_pci_handle_blast(PCIESPState *pci, uint32_t val)
static void esp_pci_handle_abort(PCIESPState *pci, uint32_t val)
{
+ ESPState *s = ESP(&pci->esp);
+
trace_esp_pci_dma_abort(val);
- if (pci->esp.current_req) {
- scsi_req_cancel(pci->esp.current_req);
+ if (s->current_req) {
+ scsi_req_cancel(s->current_req);
}
}
static void esp_pci_handle_start(PCIESPState *pci, uint32_t val)
{
+ ESPState *s = ESP(&pci->esp);
+
trace_esp_pci_dma_start(val);
pci->dma_regs[DMA_WBC] = pci->dma_regs[DMA_STC];
@@ -109,7 +115,7 @@ static void esp_pci_handle_start(PCIESPState *pci, uint32_t val)
| DMA_STAT_DONE | DMA_STAT_ABORT
| DMA_STAT_ERROR | DMA_STAT_PWDN);
- esp_dma_enable(&pci->esp, 0, 1);
+ esp_dma_enable(s, 0, 1);
}
static void esp_pci_dma_write(PCIESPState *pci, uint32_t saddr, uint32_t val)
@@ -155,11 +161,12 @@ static void esp_pci_dma_write(PCIESPState *pci, uint32_t saddr, uint32_t val)
static uint32_t esp_pci_dma_read(PCIESPState *pci, uint32_t saddr)
{
+ ESPState *s = ESP(&pci->esp);
uint32_t val;
val = pci->dma_regs[saddr];
if (saddr == DMA_STAT) {
- if (pci->esp.rregs[ESP_RSTAT] & STAT_INT) {
+ if (s->rregs[ESP_RSTAT] & STAT_INT) {
val |= DMA_STAT_SCSIINT;
}
if (!(pci->sbac & SBAC_STATUS)) {
@@ -176,6 +183,7 @@ static void esp_pci_io_write(void *opaque, hwaddr addr,
uint64_t val, unsigned int size)
{
PCIESPState *pci = opaque;
+ ESPState *s = ESP(&pci->esp);
if (size < 4 || addr & 3) {
/* need to upgrade request: we only support 4-bytes accesses */
@@ -183,7 +191,7 @@ static void esp_pci_io_write(void *opaque, hwaddr addr,
int shift;
if (addr < 0x40) {
- current = pci->esp.wregs[addr >> 2];
+ current = s->wregs[addr >> 2];
} else if (addr < 0x60) {
current = pci->dma_regs[(addr - 0x40) >> 2];
} else if (addr < 0x74) {
@@ -203,7 +211,7 @@ static void esp_pci_io_write(void *opaque, hwaddr addr,
if (addr < 0x40) {
/* SCSI core reg */
- esp_reg_write(&pci->esp, addr >> 2, val);
+ esp_reg_write(s, addr >> 2, val);
} else if (addr < 0x60) {
/* PCI DMA CCB */
esp_pci_dma_write(pci, (addr - 0x40) >> 2, val);
@@ -220,11 +228,12 @@ static uint64_t esp_pci_io_read(void *opaque, hwaddr addr,
unsigned int size)
{
PCIESPState *pci = opaque;
+ ESPState *s = ESP(&pci->esp);
uint32_t ret;
if (addr < 0x40) {
/* SCSI core reg */
- ret = esp_reg_read(&pci->esp, addr >> 2);
+ ret = esp_reg_read(s, addr >> 2);
} else if (addr < 0x60) {
/* PCI DMA CCB */
ret = esp_pci_dma_read(pci, (addr - 0x40) >> 2);
@@ -306,7 +315,9 @@ static const MemoryRegionOps esp_pci_io_ops = {
static void esp_pci_hard_reset(DeviceState *dev)
{
PCIESPState *pci = PCI_ESP(dev);
- esp_hard_reset(&pci->esp);
+ ESPState *s = ESP(&pci->esp);
+
+ esp_hard_reset(s);
pci->dma_regs[DMA_CMD] &= ~(DMA_CMD_DIR | DMA_CMD_INTE_D | DMA_CMD_INTE_P
| DMA_CMD_MDL | DMA_CMD_DIAG | DMA_CMD_MASK);
pci->dma_regs[DMA_WBC] &= ~0xffff;
@@ -353,9 +364,13 @@ static void esp_pci_scsi_realize(PCIDevice *dev, Error **errp)
{
PCIESPState *pci = PCI_ESP(dev);
DeviceState *d = DEVICE(dev);
- ESPState *s = &pci->esp;
+ ESPState *s = ESP(&pci->esp);
uint8_t *pci_conf;
+ if (!qdev_realize(DEVICE(s), NULL, errp)) {
+ return;
+ }
+
pci_conf = dev->config;
/* Interrupt pin A */
@@ -374,11 +389,19 @@ static void esp_pci_scsi_realize(PCIDevice *dev, Error **errp)
scsi_bus_new(&s->bus, sizeof(s->bus), d, &esp_pci_scsi_info, NULL);
}
-static void esp_pci_scsi_uninit(PCIDevice *d)
+static void esp_pci_scsi_exit(PCIDevice *d)
{
PCIESPState *pci = PCI_ESP(d);
+ ESPState *s = ESP(&pci->esp);
+
+ qemu_free_irq(s->irq);
+}
+
+static void esp_pci_init(Object *obj)
+{
+ PCIESPState *pci = PCI_ESP(obj);
- qemu_free_irq(pci->esp.irq);
+ object_initialize_child(obj, "esp", &pci->esp, TYPE_ESP);
}
static void esp_pci_class_init(ObjectClass *klass, void *data)
@@ -387,7 +410,7 @@ static void esp_pci_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
k->realize = esp_pci_scsi_realize;
- k->exit = esp_pci_scsi_uninit;
+ k->exit = esp_pci_scsi_exit;
k->vendor_id = PCI_VENDOR_ID_AMD;
k->device_id = PCI_DEVICE_ID_AMD_SCSI;
k->revision = 0x10;
@@ -401,6 +424,7 @@ static void esp_pci_class_init(ObjectClass *klass, void *data)
static const TypeInfo esp_pci_info = {
.name = TYPE_AM53C974_DEVICE,
.parent = TYPE_PCI_DEVICE,
+ .instance_init = esp_pci_init,
.instance_size = sizeof(PCIESPState),
.class_init = esp_pci_class_init,
.interfaces = (InterfaceInfo[]) {
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 93312a6..6f8a1d1 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -827,20 +827,22 @@ static void sysbus_esp_mem_write(void *opaque, hwaddr addr,
uint64_t val, unsigned int size)
{
SysBusESPState *sysbus = opaque;
+ ESPState *s = ESP(&sysbus->esp);
uint32_t saddr;
saddr = addr >> sysbus->it_shift;
- esp_reg_write(&sysbus->esp, saddr, val);
+ esp_reg_write(s, saddr, val);
}
static uint64_t sysbus_esp_mem_read(void *opaque, hwaddr addr,
unsigned int size)
{
SysBusESPState *sysbus = opaque;
+ ESPState *s = ESP(&sysbus->esp);
uint32_t saddr;
saddr = addr >> sysbus->it_shift;
- return esp_reg_read(&sysbus->esp, saddr);
+ return esp_reg_read(s, saddr);
}
static const MemoryRegionOps sysbus_esp_mem_ops = {
@@ -854,7 +856,7 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
uint64_t val, unsigned int size)
{
SysBusESPState *sysbus = opaque;
- ESPState *s = &sysbus->esp;
+ ESPState *s = ESP(&sysbus->esp);
uint32_t dmalen;
uint8_t *buf = get_pdma_buf(s);
@@ -891,7 +893,7 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr,
unsigned int size)
{
SysBusESPState *sysbus = opaque;
- ESPState *s = &sysbus->esp;
+ ESPState *s = ESP(&sysbus->esp);
uint8_t *buf = get_pdma_buf(s);
uint64_t val = 0;
@@ -939,7 +941,7 @@ static const struct SCSIBusInfo esp_scsi_info = {
static void sysbus_esp_gpio_demux(void *opaque, int irq, int level)
{
SysBusESPState *sysbus = SYSBUS_ESP(opaque);
- ESPState *s = &sysbus->esp;
+ ESPState *s = ESP(&sysbus->esp);
switch (irq) {
case 0:
@@ -955,7 +957,11 @@ static void sysbus_esp_realize(DeviceState *dev, Error **errp)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
SysBusESPState *sysbus = SYSBUS_ESP(dev);
- ESPState *s = &sysbus->esp;
+ ESPState *s = ESP(&sysbus->esp);
+
+ if (!qdev_realize(DEVICE(s), NULL, errp)) {
+ return;
+ }
sysbus_init_irq(sbd, &s->irq);
sysbus_init_irq(sbd, &s->irq_data);
@@ -977,7 +983,16 @@ static void sysbus_esp_realize(DeviceState *dev, Error **errp)
static void sysbus_esp_hard_reset(DeviceState *dev)
{
SysBusESPState *sysbus = SYSBUS_ESP(dev);
- esp_hard_reset(&sysbus->esp);
+ ESPState *s = ESP(&sysbus->esp);
+
+ esp_hard_reset(s);
+}
+
+static void sysbus_esp_init(Object *obj)
+{
+ SysBusESPState *sysbus = SYSBUS_ESP(obj);
+
+ object_initialize_child(obj, "esp", &sysbus->esp, TYPE_ESP);
}
static const VMStateDescription vmstate_sysbus_esp_scsi = {
@@ -1003,13 +1018,31 @@ static void sysbus_esp_class_init(ObjectClass *klass, void *data)
static const TypeInfo sysbus_esp_info = {
.name = TYPE_SYSBUS_ESP,
.parent = TYPE_SYS_BUS_DEVICE,
+ .instance_init = sysbus_esp_init,
.instance_size = sizeof(SysBusESPState),
.class_init = sysbus_esp_class_init,
};
+static void esp_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ /* internal device for sysbusesp/pciespscsi, not user-creatable */
+ dc->user_creatable = false;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+}
+
+static const TypeInfo esp_info = {
+ .name = TYPE_ESP,
+ .parent = TYPE_DEVICE,
+ .instance_size = sizeof(ESPState),
+ .class_init = esp_class_init,
+};
+
static void esp_register_types(void)
{
type_register_static(&sysbus_esp_info);
+ type_register_static(&esp_info);
}
type_init(esp_register_types)
diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
index 8a0740e..af23f81 100644
--- a/include/hw/scsi/esp.h
+++ b/include/hw/scsi/esp.h
@@ -22,7 +22,12 @@ enum pdma_origin_id {
ASYNC,
};
+#define TYPE_ESP "esp"
+OBJECT_DECLARE_SIMPLE_TYPE(ESPState, ESP)
+
struct ESPState {
+ DeviceState parent_obj;
+
uint8_t rregs[ESP_REGS];
uint8_t wregs[ESP_REGS];
qemu_irq irq;