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>
This commit is contained in:
parent
84fbefedfe
commit
eb169c76d0
@ -79,8 +79,10 @@ struct PCIESPState {
|
|||||||
|
|
||||||
static void esp_pci_handle_idle(PCIESPState *pci, uint32_t val)
|
static void esp_pci_handle_idle(PCIESPState *pci, uint32_t val)
|
||||||
{
|
{
|
||||||
|
ESPState *s = ESP(&pci->esp);
|
||||||
|
|
||||||
trace_esp_pci_dma_idle(val);
|
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)
|
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)
|
static void esp_pci_handle_abort(PCIESPState *pci, uint32_t val)
|
||||||
{
|
{
|
||||||
|
ESPState *s = ESP(&pci->esp);
|
||||||
|
|
||||||
trace_esp_pci_dma_abort(val);
|
trace_esp_pci_dma_abort(val);
|
||||||
if (pci->esp.current_req) {
|
if (s->current_req) {
|
||||||
scsi_req_cancel(pci->esp.current_req);
|
scsi_req_cancel(s->current_req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void esp_pci_handle_start(PCIESPState *pci, uint32_t val)
|
static void esp_pci_handle_start(PCIESPState *pci, uint32_t val)
|
||||||
{
|
{
|
||||||
|
ESPState *s = ESP(&pci->esp);
|
||||||
|
|
||||||
trace_esp_pci_dma_start(val);
|
trace_esp_pci_dma_start(val);
|
||||||
|
|
||||||
pci->dma_regs[DMA_WBC] = pci->dma_regs[DMA_STC];
|
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_DONE | DMA_STAT_ABORT
|
||||||
| DMA_STAT_ERROR | DMA_STAT_PWDN);
|
| 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)
|
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)
|
static uint32_t esp_pci_dma_read(PCIESPState *pci, uint32_t saddr)
|
||||||
{
|
{
|
||||||
|
ESPState *s = ESP(&pci->esp);
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
|
|
||||||
val = pci->dma_regs[saddr];
|
val = pci->dma_regs[saddr];
|
||||||
if (saddr == DMA_STAT) {
|
if (saddr == DMA_STAT) {
|
||||||
if (pci->esp.rregs[ESP_RSTAT] & STAT_INT) {
|
if (s->rregs[ESP_RSTAT] & STAT_INT) {
|
||||||
val |= DMA_STAT_SCSIINT;
|
val |= DMA_STAT_SCSIINT;
|
||||||
}
|
}
|
||||||
if (!(pci->sbac & SBAC_STATUS)) {
|
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)
|
uint64_t val, unsigned int size)
|
||||||
{
|
{
|
||||||
PCIESPState *pci = opaque;
|
PCIESPState *pci = opaque;
|
||||||
|
ESPState *s = ESP(&pci->esp);
|
||||||
|
|
||||||
if (size < 4 || addr & 3) {
|
if (size < 4 || addr & 3) {
|
||||||
/* need to upgrade request: we only support 4-bytes accesses */
|
/* 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;
|
int shift;
|
||||||
|
|
||||||
if (addr < 0x40) {
|
if (addr < 0x40) {
|
||||||
current = pci->esp.wregs[addr >> 2];
|
current = s->wregs[addr >> 2];
|
||||||
} else if (addr < 0x60) {
|
} else if (addr < 0x60) {
|
||||||
current = pci->dma_regs[(addr - 0x40) >> 2];
|
current = pci->dma_regs[(addr - 0x40) >> 2];
|
||||||
} else if (addr < 0x74) {
|
} else if (addr < 0x74) {
|
||||||
@ -203,7 +211,7 @@ static void esp_pci_io_write(void *opaque, hwaddr addr,
|
|||||||
|
|
||||||
if (addr < 0x40) {
|
if (addr < 0x40) {
|
||||||
/* SCSI core reg */
|
/* SCSI core reg */
|
||||||
esp_reg_write(&pci->esp, addr >> 2, val);
|
esp_reg_write(s, addr >> 2, val);
|
||||||
} else if (addr < 0x60) {
|
} else if (addr < 0x60) {
|
||||||
/* PCI DMA CCB */
|
/* PCI DMA CCB */
|
||||||
esp_pci_dma_write(pci, (addr - 0x40) >> 2, val);
|
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)
|
unsigned int size)
|
||||||
{
|
{
|
||||||
PCIESPState *pci = opaque;
|
PCIESPState *pci = opaque;
|
||||||
|
ESPState *s = ESP(&pci->esp);
|
||||||
uint32_t ret;
|
uint32_t ret;
|
||||||
|
|
||||||
if (addr < 0x40) {
|
if (addr < 0x40) {
|
||||||
/* SCSI core reg */
|
/* SCSI core reg */
|
||||||
ret = esp_reg_read(&pci->esp, addr >> 2);
|
ret = esp_reg_read(s, addr >> 2);
|
||||||
} else if (addr < 0x60) {
|
} else if (addr < 0x60) {
|
||||||
/* PCI DMA CCB */
|
/* PCI DMA CCB */
|
||||||
ret = esp_pci_dma_read(pci, (addr - 0x40) >> 2);
|
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)
|
static void esp_pci_hard_reset(DeviceState *dev)
|
||||||
{
|
{
|
||||||
PCIESPState *pci = PCI_ESP(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
|
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);
|
| DMA_CMD_MDL | DMA_CMD_DIAG | DMA_CMD_MASK);
|
||||||
pci->dma_regs[DMA_WBC] &= ~0xffff;
|
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);
|
PCIESPState *pci = PCI_ESP(dev);
|
||||||
DeviceState *d = DEVICE(dev);
|
DeviceState *d = DEVICE(dev);
|
||||||
ESPState *s = &pci->esp;
|
ESPState *s = ESP(&pci->esp);
|
||||||
uint8_t *pci_conf;
|
uint8_t *pci_conf;
|
||||||
|
|
||||||
|
if (!qdev_realize(DEVICE(s), NULL, errp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pci_conf = dev->config;
|
pci_conf = dev->config;
|
||||||
|
|
||||||
/* Interrupt pin A */
|
/* 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);
|
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);
|
PCIESPState *pci = PCI_ESP(d);
|
||||||
|
ESPState *s = ESP(&pci->esp);
|
||||||
|
|
||||||
qemu_free_irq(pci->esp.irq);
|
qemu_free_irq(s->irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void esp_pci_init(Object *obj)
|
||||||
|
{
|
||||||
|
PCIESPState *pci = PCI_ESP(obj);
|
||||||
|
|
||||||
|
object_initialize_child(obj, "esp", &pci->esp, TYPE_ESP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void esp_pci_class_init(ObjectClass *klass, void *data)
|
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);
|
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||||
|
|
||||||
k->realize = esp_pci_scsi_realize;
|
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->vendor_id = PCI_VENDOR_ID_AMD;
|
||||||
k->device_id = PCI_DEVICE_ID_AMD_SCSI;
|
k->device_id = PCI_DEVICE_ID_AMD_SCSI;
|
||||||
k->revision = 0x10;
|
k->revision = 0x10;
|
||||||
@ -401,6 +424,7 @@ static void esp_pci_class_init(ObjectClass *klass, void *data)
|
|||||||
static const TypeInfo esp_pci_info = {
|
static const TypeInfo esp_pci_info = {
|
||||||
.name = TYPE_AM53C974_DEVICE,
|
.name = TYPE_AM53C974_DEVICE,
|
||||||
.parent = TYPE_PCI_DEVICE,
|
.parent = TYPE_PCI_DEVICE,
|
||||||
|
.instance_init = esp_pci_init,
|
||||||
.instance_size = sizeof(PCIESPState),
|
.instance_size = sizeof(PCIESPState),
|
||||||
.class_init = esp_pci_class_init,
|
.class_init = esp_pci_class_init,
|
||||||
.interfaces = (InterfaceInfo[]) {
|
.interfaces = (InterfaceInfo[]) {
|
||||||
|
@ -827,20 +827,22 @@ static void sysbus_esp_mem_write(void *opaque, hwaddr addr,
|
|||||||
uint64_t val, unsigned int size)
|
uint64_t val, unsigned int size)
|
||||||
{
|
{
|
||||||
SysBusESPState *sysbus = opaque;
|
SysBusESPState *sysbus = opaque;
|
||||||
|
ESPState *s = ESP(&sysbus->esp);
|
||||||
uint32_t saddr;
|
uint32_t saddr;
|
||||||
|
|
||||||
saddr = addr >> sysbus->it_shift;
|
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,
|
static uint64_t sysbus_esp_mem_read(void *opaque, hwaddr addr,
|
||||||
unsigned int size)
|
unsigned int size)
|
||||||
{
|
{
|
||||||
SysBusESPState *sysbus = opaque;
|
SysBusESPState *sysbus = opaque;
|
||||||
|
ESPState *s = ESP(&sysbus->esp);
|
||||||
uint32_t saddr;
|
uint32_t saddr;
|
||||||
|
|
||||||
saddr = addr >> sysbus->it_shift;
|
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 = {
|
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)
|
uint64_t val, unsigned int size)
|
||||||
{
|
{
|
||||||
SysBusESPState *sysbus = opaque;
|
SysBusESPState *sysbus = opaque;
|
||||||
ESPState *s = &sysbus->esp;
|
ESPState *s = ESP(&sysbus->esp);
|
||||||
uint32_t dmalen;
|
uint32_t dmalen;
|
||||||
uint8_t *buf = get_pdma_buf(s);
|
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)
|
unsigned int size)
|
||||||
{
|
{
|
||||||
SysBusESPState *sysbus = opaque;
|
SysBusESPState *sysbus = opaque;
|
||||||
ESPState *s = &sysbus->esp;
|
ESPState *s = ESP(&sysbus->esp);
|
||||||
uint8_t *buf = get_pdma_buf(s);
|
uint8_t *buf = get_pdma_buf(s);
|
||||||
uint64_t val = 0;
|
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)
|
static void sysbus_esp_gpio_demux(void *opaque, int irq, int level)
|
||||||
{
|
{
|
||||||
SysBusESPState *sysbus = SYSBUS_ESP(opaque);
|
SysBusESPState *sysbus = SYSBUS_ESP(opaque);
|
||||||
ESPState *s = &sysbus->esp;
|
ESPState *s = ESP(&sysbus->esp);
|
||||||
|
|
||||||
switch (irq) {
|
switch (irq) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -955,7 +957,11 @@ static void sysbus_esp_realize(DeviceState *dev, Error **errp)
|
|||||||
{
|
{
|
||||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||||
SysBusESPState *sysbus = SYSBUS_ESP(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);
|
||||||
sysbus_init_irq(sbd, &s->irq_data);
|
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)
|
static void sysbus_esp_hard_reset(DeviceState *dev)
|
||||||
{
|
{
|
||||||
SysBusESPState *sysbus = SYSBUS_ESP(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 = {
|
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 = {
|
static const TypeInfo sysbus_esp_info = {
|
||||||
.name = TYPE_SYSBUS_ESP,
|
.name = TYPE_SYSBUS_ESP,
|
||||||
.parent = TYPE_SYS_BUS_DEVICE,
|
.parent = TYPE_SYS_BUS_DEVICE,
|
||||||
|
.instance_init = sysbus_esp_init,
|
||||||
.instance_size = sizeof(SysBusESPState),
|
.instance_size = sizeof(SysBusESPState),
|
||||||
.class_init = sysbus_esp_class_init,
|
.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)
|
static void esp_register_types(void)
|
||||||
{
|
{
|
||||||
type_register_static(&sysbus_esp_info);
|
type_register_static(&sysbus_esp_info);
|
||||||
|
type_register_static(&esp_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
type_init(esp_register_types)
|
type_init(esp_register_types)
|
||||||
|
@ -22,7 +22,12 @@ enum pdma_origin_id {
|
|||||||
ASYNC,
|
ASYNC,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TYPE_ESP "esp"
|
||||||
|
OBJECT_DECLARE_SIMPLE_TYPE(ESPState, ESP)
|
||||||
|
|
||||||
struct ESPState {
|
struct ESPState {
|
||||||
|
DeviceState parent_obj;
|
||||||
|
|
||||||
uint8_t rregs[ESP_REGS];
|
uint8_t rregs[ESP_REGS];
|
||||||
uint8_t wregs[ESP_REGS];
|
uint8_t wregs[ESP_REGS];
|
||||||
qemu_irq irq;
|
qemu_irq irq;
|
||||||
|
Loading…
Reference in New Issue
Block a user