Message ID | 20210209193018.31339-39-mark.cave-ayland@ilande.co.uk (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | esp: consolidate PDMA transfer buffers and other fixes | expand |
On 2/9/21 8:30 PM, Mark Cave-Ayland wrote: > Rename TI_BUFSZ to ESP_FIFO_SZ since this constant is really describing the size > of the FIFO and is not directly related to the TI size. > > Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> > --- > hw/scsi/esp.c | 117 ++++++++++++++++++++++++++---------------- > include/hw/scsi/esp.h | 8 +-- > 2 files changed, 79 insertions(+), 46 deletions(-) > @@ -806,11 +818,9 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) > } else { > trace_esp_error_fifo_overrun(); > } > - } else if (s->ti_wptr == TI_BUFSZ - 1) { > - trace_esp_error_fifo_overrun(); > } else { > s->ti_size++; > - s->ti_buf[s->ti_wptr++] = val & 0xff; > + esp_fifo_push(s, val & 0xff); Personally I'd drop the '& 0xff' part. > } > > /* Non-DMA transfers raise an interrupt after every byte */ > @@ -839,8 +849,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) > case CMD_FLUSH: > trace_esp_mem_writeb_cmd_flush(val); > /*s->ti_size = 0;*/ Is this comment still meaningful? > - s->ti_wptr = 0; > - s->ti_rptr = 0; > + fifo8_reset(&s->fifo); > break; > case CMD_RESET: > trace_esp_mem_writeb_cmd_reset(val); > @@ -958,11 +967,18 @@ static int esp_pre_save(void *opaque) > static int esp_post_load(void *opaque, int version_id) > { > ESPState *s = ESP(opaque); > + int len, i; > > version_id = MIN(version_id, s->mig_version_id); > > if (version_id < 5) { > esp_set_tc(s, s->mig_dma_left); > + > + /* Migrate ti_buf to fifo */ > + len = s->mig_ti_wptr - s->mig_ti_rptr; > + for (i = 0; i < len; i++) { > + fifo8_push(&s->fifo, s->mig_ti_buf[i]); Again I dare to add: Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> > + } > }
On 23/02/2021 18:49, Philippe Mathieu-Daudé wrote: > On 2/9/21 8:30 PM, Mark Cave-Ayland wrote: >> Rename TI_BUFSZ to ESP_FIFO_SZ since this constant is really describing the size >> of the FIFO and is not directly related to the TI size. >> >> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> >> --- >> hw/scsi/esp.c | 117 ++++++++++++++++++++++++++---------------- >> include/hw/scsi/esp.h | 8 +-- >> 2 files changed, 79 insertions(+), 46 deletions(-) > >> @@ -806,11 +818,9 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) >> } else { >> trace_esp_error_fifo_overrun(); >> } >> - } else if (s->ti_wptr == TI_BUFSZ - 1) { >> - trace_esp_error_fifo_overrun(); >> } else { >> s->ti_size++; >> - s->ti_buf[s->ti_wptr++] = val & 0xff; >> + esp_fifo_push(s, val & 0xff); > > Personally I'd drop the '& 0xff' part. I left it as it was so that it was direct translation of the code it was replacing, but I can easily drop it. >> } >> >> /* Non-DMA transfers raise an interrupt after every byte */ >> @@ -839,8 +849,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) >> case CMD_FLUSH: >> trace_esp_mem_writeb_cmd_flush(val); >> /*s->ti_size = 0;*/ > > Is this comment still meaningful? This line can also be removed, so I will make this change for v3. >> - s->ti_wptr = 0; >> - s->ti_rptr = 0; >> + fifo8_reset(&s->fifo); >> break; >> case CMD_RESET: >> trace_esp_mem_writeb_cmd_reset(val); >> @@ -958,11 +967,18 @@ static int esp_pre_save(void *opaque) >> static int esp_post_load(void *opaque, int version_id) >> { >> ESPState *s = ESP(opaque); >> + int len, i; >> >> version_id = MIN(version_id, s->mig_version_id); >> >> if (version_id < 5) { >> esp_set_tc(s, s->mig_dma_left); >> + >> + /* Migrate ti_buf to fifo */ >> + len = s->mig_ti_wptr - s->mig_ti_rptr; >> + for (i = 0; i < len; i++) { >> + fifo8_push(&s->fifo, s->mig_ti_buf[i]); > > Again I dare to add: > Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Thank you :) ATB, Mark.
Le 09/02/2021 à 20:30, Mark Cave-Ayland a écrit : > Rename TI_BUFSZ to ESP_FIFO_SZ since this constant is really describing the size > of the FIFO and is not directly related to the TI size. > > Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> > --- > hw/scsi/esp.c | 117 ++++++++++++++++++++++++++---------------- > include/hw/scsi/esp.h | 8 +-- > 2 files changed, 79 insertions(+), 46 deletions(-) > > diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c > index 5a66b7d710..98df357276 100644 > --- a/hw/scsi/esp.c > +++ b/hw/scsi/esp.c > @@ -98,6 +98,25 @@ void esp_request_cancelled(SCSIRequest *req) > } > } > > +static void esp_fifo_push(ESPState *s, uint8_t val) > +{ > + if (fifo8_num_used(&s->fifo) == ESP_FIFO_SZ) { > + trace_esp_error_fifo_overrun(); > + return; > + } > + > + fifo8_push(&s->fifo, val); > +} > + > +static uint8_t esp_fifo_pop(ESPState *s) > +{ > + if (fifo8_is_empty(&s->fifo)) { > + return 0; > + } > + > + return fifo8_pop(&s->fifo); > +} > + > static uint32_t esp_get_tc(ESPState *s) > { > uint32_t dmalen; > @@ -134,7 +153,7 @@ static uint8_t esp_pdma_read(ESPState *s) > if (s->do_cmd) { > val = s->cmdbuf[s->cmdlen++]; > } else { > - val = s->ti_buf[s->ti_rptr++]; > + val = esp_fifo_pop(s); > } > > return val; > @@ -151,7 +170,7 @@ static void esp_pdma_write(ESPState *s, uint8_t val) > if (s->do_cmd) { > s->cmdbuf[s->cmdlen++] = val; > } else { > - s->ti_buf[s->ti_wptr++] = val; > + esp_fifo_push(s, val); > } > > dmalen--; > @@ -165,8 +184,7 @@ static int esp_select(ESPState *s) > target = s->wregs[ESP_WBUSID] & BUSID_DID; > > s->ti_size = 0; > - s->ti_rptr = 0; > - s->ti_wptr = 0; > + fifo8_reset(&s->fifo); > > if (s->current_req) { > /* Started a new command before the old one finished. Cancel it. */ > @@ -197,7 +215,7 @@ static int esp_select(ESPState *s) > static uint32_t get_cmd(ESPState *s, uint32_t maxlen) > { > uint8_t *buf = s->cmdbuf; > - uint32_t dmalen; > + uint32_t dmalen, n; > int target; > > target = s->wregs[ESP_WBUSID] & BUSID_DID; > @@ -220,7 +238,7 @@ static uint32_t get_cmd(ESPState *s, uint32_t maxlen) > if (dmalen == 0) { > return 0; > } > - memcpy(buf, s->ti_buf, dmalen); > + memcpy(buf, fifo8_pop_buf(&s->fifo, dmalen, &n), dmalen); > if (dmalen >= 3) { > buf[0] = buf[2] >> 5; > } > @@ -392,12 +410,18 @@ static void write_response_pdma_cb(ESPState *s) > > static void write_response(ESPState *s) > { > + uint32_t n; > + > trace_esp_write_response(s->status); > - s->ti_buf[0] = s->status; > - s->ti_buf[1] = 0; > + > + fifo8_reset(&s->fifo); > + esp_fifo_push(s, s->status); > + esp_fifo_push(s, 0); > + > if (s->dma) { > if (s->dma_memory_write) { > - s->dma_memory_write(s->dma_opaque, s->ti_buf, 2); > + s->dma_memory_write(s->dma_opaque, > + (uint8_t *)fifo8_pop_buf(&s->fifo, 2, &n), 2); > s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST; > s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC; > s->rregs[ESP_RSEQ] = SEQ_CD; > @@ -408,8 +432,6 @@ static void write_response(ESPState *s) > } > } else { > s->ti_size = 2; > - s->ti_rptr = 0; > - s->ti_wptr = 2; > s->rregs[ESP_RFLAGS] = 2; > } > esp_raise_irq(s); > @@ -429,6 +451,7 @@ static void do_dma_pdma_cb(ESPState *s) > { > int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO); > int len; > + uint32_t n; > > if (s->do_cmd) { > s->ti_size = 0; > @@ -441,10 +464,8 @@ static void do_dma_pdma_cb(ESPState *s) > > if (to_device) { > /* Copy FIFO data to device */ > - len = MIN(s->ti_wptr, TI_BUFSZ); > - memcpy(s->async_buf, s->ti_buf, len); > - s->ti_wptr = 0; > - s->ti_rptr = 0; > + len = MIN(fifo8_num_used(&s->fifo), ESP_FIFO_SZ); > + memcpy(s->async_buf, fifo8_pop_buf(&s->fifo, len, &n), len); > s->async_buf += len; > s->async_len -= len; > s->ti_size += len; > @@ -477,11 +498,8 @@ static void do_dma_pdma_cb(ESPState *s) > > if (esp_get_tc(s) != 0) { > /* Copy device data to FIFO */ > - s->ti_wptr = 0; > - s->ti_rptr = 0; > - len = MIN(s->async_len, TI_BUFSZ); > - memcpy(s->ti_buf, s->async_buf, len); > - s->ti_wptr += len; > + len = MIN(s->async_len, fifo8_num_free(&s->fifo)); > + fifo8_push_all(&s->fifo, s->async_buf, len); > s->async_buf += len; > s->async_len -= len; > s->ti_size -= len; > @@ -561,9 +579,8 @@ static void esp_do_dma(ESPState *s) > s->dma_memory_write(s->dma_opaque, s->async_buf, len); > } else { > /* Copy device data to FIFO */ > - len = MIN(len, TI_BUFSZ - s->ti_wptr); > - memcpy(&s->ti_buf[s->ti_wptr], s->async_buf, len); > - s->ti_wptr += len; > + len = MIN(len, fifo8_num_free(&s->fifo)); > + fifo8_push_all(&s->fifo, s->async_buf, len); > s->async_buf += len; > s->async_len -= len; > s->ti_size -= len; > @@ -717,8 +734,7 @@ void esp_hard_reset(ESPState *s) > memset(s->wregs, 0, ESP_REGS); > s->tchi_written = 0; > s->ti_size = 0; > - s->ti_rptr = 0; > - s->ti_wptr = 0; > + fifo8_reset(&s->fifo); > s->dma = 0; > s->do_cmd = 0; > s->dma_cb = NULL; > @@ -750,13 +766,9 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr) > /* Data out. */ > qemu_log_mask(LOG_UNIMP, "esp: PIO data read not implemented\n"); > s->rregs[ESP_FIFO] = 0; > - } else if (s->ti_rptr < s->ti_wptr) { > + } else { > s->ti_size--; > - s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++]; > - } > - if (s->ti_rptr == s->ti_wptr) { > - s->ti_rptr = 0; > - s->ti_wptr = 0; > + s->rregs[ESP_FIFO] = esp_fifo_pop(s); > } > val = s->rregs[ESP_FIFO]; > break; > @@ -806,11 +818,9 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) > } else { > trace_esp_error_fifo_overrun(); > } > - } else if (s->ti_wptr == TI_BUFSZ - 1) { > - trace_esp_error_fifo_overrun(); > } else { > s->ti_size++; > - s->ti_buf[s->ti_wptr++] = val & 0xff; > + esp_fifo_push(s, val & 0xff); > } > > /* Non-DMA transfers raise an interrupt after every byte */ > @@ -839,8 +849,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) > case CMD_FLUSH: > trace_esp_mem_writeb_cmd_flush(val); > /*s->ti_size = 0;*/ > - s->ti_wptr = 0; > - s->ti_rptr = 0; > + fifo8_reset(&s->fifo); > break; > case CMD_RESET: > trace_esp_mem_writeb_cmd_reset(val); > @@ -958,11 +967,18 @@ static int esp_pre_save(void *opaque) > static int esp_post_load(void *opaque, int version_id) > { > ESPState *s = ESP(opaque); > + int len, i; > > version_id = MIN(version_id, s->mig_version_id); > > if (version_id < 5) { > esp_set_tc(s, s->mig_dma_left); > + > + /* Migrate ti_buf to fifo */ > + len = s->mig_ti_wptr - s->mig_ti_rptr; > + for (i = 0; i < len; i++) { > + fifo8_push(&s->fifo, s->mig_ti_buf[i]); > + } > } > > s->mig_version_id = vmstate_esp.version_id; > @@ -979,9 +995,9 @@ const VMStateDescription vmstate_esp = { > VMSTATE_BUFFER(rregs, ESPState), > VMSTATE_BUFFER(wregs, ESPState), > VMSTATE_INT32(ti_size, ESPState), > - VMSTATE_UINT32(ti_rptr, ESPState), > - VMSTATE_UINT32(ti_wptr, ESPState), > - VMSTATE_BUFFER(ti_buf, ESPState), > + VMSTATE_UINT32_TEST(mig_ti_rptr, ESPState, esp_is_before_version_5), > + VMSTATE_UINT32_TEST(mig_ti_wptr, ESPState, esp_is_before_version_5), > + VMSTATE_BUFFER_TEST(mig_ti_buf, ESPState, esp_is_before_version_5), > VMSTATE_UINT32(status, ESPState), > VMSTATE_UINT32_TEST(mig_deferred_status, ESPState, > esp_is_before_version_5), > @@ -995,6 +1011,7 @@ const VMStateDescription vmstate_esp = { > VMSTATE_UINT32_TEST(mig_dma_left, ESPState, esp_is_before_version_5), > VMSTATE_BOOL_TEST(data_in_ready, ESPState, esp_is_version_5), > VMSTATE_UINT8_TEST(cmdbuf_cdb_offset, ESPState, esp_is_version_5), > + VMSTATE_FIFO8_TEST(fifo, ESPState, esp_is_version_5), > VMSTATE_END_OF_LIST() > }, > }; > @@ -1047,7 +1064,7 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr, > break; > } > dmalen = esp_get_tc(s); > - if (dmalen == 0 || (s->ti_wptr == TI_BUFSZ)) { > + if (dmalen == 0 || fifo8_is_full(&s->fifo)) { > s->pdma_cb(s); > } > } > @@ -1070,9 +1087,7 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr, > val = (val << 8) | esp_pdma_read(s); > break; > } > - if (s->ti_rptr == s->ti_wptr) { > - s->ti_wptr = 0; > - s->ti_rptr = 0; > + if (fifo8_is_empty(&s->fifo)) { > s->pdma_cb(s); > } > return val; > @@ -1182,6 +1197,20 @@ static const TypeInfo sysbus_esp_info = { > .class_init = sysbus_esp_class_init, > }; > > +static void esp_finalize(Object *obj) > +{ > + ESPState *s = ESP(obj); > + > + fifo8_destroy(&s->fifo); > +} > + > +static void esp_init(Object *obj) > +{ > + ESPState *s = ESP(obj); > + > + fifo8_create(&s->fifo, ESP_FIFO_SZ); > +} > + > static void esp_class_init(ObjectClass *klass, void *data) > { > DeviceClass *dc = DEVICE_CLASS(klass); > @@ -1194,6 +1223,8 @@ static void esp_class_init(ObjectClass *klass, void *data) > static const TypeInfo esp_info = { > .name = TYPE_ESP, > .parent = TYPE_DEVICE, > + .instance_init = esp_init, > + .instance_finalize = esp_finalize, > .instance_size = sizeof(ESPState), > .class_init = esp_class_init, > }; > diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h > index 6f3bf4a0ce..063d9b1caa 100644 > --- a/include/hw/scsi/esp.h > +++ b/include/hw/scsi/esp.h > @@ -3,6 +3,7 @@ > > #include "hw/scsi/scsi.h" > #include "hw/sysbus.h" > +#include "qemu/fifo8.h" > #include "qom/object.h" > > /* esp.c */ > @@ -10,7 +11,7 @@ > typedef void (*ESPDMAMemoryReadWriteFunc)(void *opaque, uint8_t *buf, int len); > > #define ESP_REGS 16 > -#define TI_BUFSZ 16 > +#define ESP_FIFO_SZ 16 > #define ESP_CMDBUF_SZ 32 > > typedef struct ESPState ESPState; > @@ -28,10 +29,9 @@ struct ESPState { > uint8_t chip_id; > bool tchi_written; > int32_t ti_size; > - uint32_t ti_rptr, ti_wptr; > uint32_t status; > uint32_t dma; > - uint8_t ti_buf[TI_BUFSZ]; > + Fifo8 fifo; > SCSIBus bus; > SCSIDevice *current_dev; > SCSIRequest *current_req; > @@ -58,6 +58,8 @@ struct ESPState { > uint32_t mig_dma_left; > uint32_t mig_deferred_status; > bool mig_deferred_complete; > + uint32_t mig_ti_rptr, mig_ti_wptr; > + uint8_t mig_ti_buf[ESP_FIFO_SZ]; > }; > > #define TYPE_SYSBUS_ESP "sysbus-esp" > Reviewed-by: Laurent Vivier <laurent@vivier.eu>
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c index 5a66b7d710..98df357276 100644 --- a/hw/scsi/esp.c +++ b/hw/scsi/esp.c @@ -98,6 +98,25 @@ void esp_request_cancelled(SCSIRequest *req) } } +static void esp_fifo_push(ESPState *s, uint8_t val) +{ + if (fifo8_num_used(&s->fifo) == ESP_FIFO_SZ) { + trace_esp_error_fifo_overrun(); + return; + } + + fifo8_push(&s->fifo, val); +} + +static uint8_t esp_fifo_pop(ESPState *s) +{ + if (fifo8_is_empty(&s->fifo)) { + return 0; + } + + return fifo8_pop(&s->fifo); +} + static uint32_t esp_get_tc(ESPState *s) { uint32_t dmalen; @@ -134,7 +153,7 @@ static uint8_t esp_pdma_read(ESPState *s) if (s->do_cmd) { val = s->cmdbuf[s->cmdlen++]; } else { - val = s->ti_buf[s->ti_rptr++]; + val = esp_fifo_pop(s); } return val; @@ -151,7 +170,7 @@ static void esp_pdma_write(ESPState *s, uint8_t val) if (s->do_cmd) { s->cmdbuf[s->cmdlen++] = val; } else { - s->ti_buf[s->ti_wptr++] = val; + esp_fifo_push(s, val); } dmalen--; @@ -165,8 +184,7 @@ static int esp_select(ESPState *s) target = s->wregs[ESP_WBUSID] & BUSID_DID; s->ti_size = 0; - s->ti_rptr = 0; - s->ti_wptr = 0; + fifo8_reset(&s->fifo); if (s->current_req) { /* Started a new command before the old one finished. Cancel it. */ @@ -197,7 +215,7 @@ static int esp_select(ESPState *s) static uint32_t get_cmd(ESPState *s, uint32_t maxlen) { uint8_t *buf = s->cmdbuf; - uint32_t dmalen; + uint32_t dmalen, n; int target; target = s->wregs[ESP_WBUSID] & BUSID_DID; @@ -220,7 +238,7 @@ static uint32_t get_cmd(ESPState *s, uint32_t maxlen) if (dmalen == 0) { return 0; } - memcpy(buf, s->ti_buf, dmalen); + memcpy(buf, fifo8_pop_buf(&s->fifo, dmalen, &n), dmalen); if (dmalen >= 3) { buf[0] = buf[2] >> 5; } @@ -392,12 +410,18 @@ static void write_response_pdma_cb(ESPState *s) static void write_response(ESPState *s) { + uint32_t n; + trace_esp_write_response(s->status); - s->ti_buf[0] = s->status; - s->ti_buf[1] = 0; + + fifo8_reset(&s->fifo); + esp_fifo_push(s, s->status); + esp_fifo_push(s, 0); + if (s->dma) { if (s->dma_memory_write) { - s->dma_memory_write(s->dma_opaque, s->ti_buf, 2); + s->dma_memory_write(s->dma_opaque, + (uint8_t *)fifo8_pop_buf(&s->fifo, 2, &n), 2); s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST; s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC; s->rregs[ESP_RSEQ] = SEQ_CD; @@ -408,8 +432,6 @@ static void write_response(ESPState *s) } } else { s->ti_size = 2; - s->ti_rptr = 0; - s->ti_wptr = 2; s->rregs[ESP_RFLAGS] = 2; } esp_raise_irq(s); @@ -429,6 +451,7 @@ static void do_dma_pdma_cb(ESPState *s) { int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO); int len; + uint32_t n; if (s->do_cmd) { s->ti_size = 0; @@ -441,10 +464,8 @@ static void do_dma_pdma_cb(ESPState *s) if (to_device) { /* Copy FIFO data to device */ - len = MIN(s->ti_wptr, TI_BUFSZ); - memcpy(s->async_buf, s->ti_buf, len); - s->ti_wptr = 0; - s->ti_rptr = 0; + len = MIN(fifo8_num_used(&s->fifo), ESP_FIFO_SZ); + memcpy(s->async_buf, fifo8_pop_buf(&s->fifo, len, &n), len); s->async_buf += len; s->async_len -= len; s->ti_size += len; @@ -477,11 +498,8 @@ static void do_dma_pdma_cb(ESPState *s) if (esp_get_tc(s) != 0) { /* Copy device data to FIFO */ - s->ti_wptr = 0; - s->ti_rptr = 0; - len = MIN(s->async_len, TI_BUFSZ); - memcpy(s->ti_buf, s->async_buf, len); - s->ti_wptr += len; + len = MIN(s->async_len, fifo8_num_free(&s->fifo)); + fifo8_push_all(&s->fifo, s->async_buf, len); s->async_buf += len; s->async_len -= len; s->ti_size -= len; @@ -561,9 +579,8 @@ static void esp_do_dma(ESPState *s) s->dma_memory_write(s->dma_opaque, s->async_buf, len); } else { /* Copy device data to FIFO */ - len = MIN(len, TI_BUFSZ - s->ti_wptr); - memcpy(&s->ti_buf[s->ti_wptr], s->async_buf, len); - s->ti_wptr += len; + len = MIN(len, fifo8_num_free(&s->fifo)); + fifo8_push_all(&s->fifo, s->async_buf, len); s->async_buf += len; s->async_len -= len; s->ti_size -= len; @@ -717,8 +734,7 @@ void esp_hard_reset(ESPState *s) memset(s->wregs, 0, ESP_REGS); s->tchi_written = 0; s->ti_size = 0; - s->ti_rptr = 0; - s->ti_wptr = 0; + fifo8_reset(&s->fifo); s->dma = 0; s->do_cmd = 0; s->dma_cb = NULL; @@ -750,13 +766,9 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr) /* Data out. */ qemu_log_mask(LOG_UNIMP, "esp: PIO data read not implemented\n"); s->rregs[ESP_FIFO] = 0; - } else if (s->ti_rptr < s->ti_wptr) { + } else { s->ti_size--; - s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++]; - } - if (s->ti_rptr == s->ti_wptr) { - s->ti_rptr = 0; - s->ti_wptr = 0; + s->rregs[ESP_FIFO] = esp_fifo_pop(s); } val = s->rregs[ESP_FIFO]; break; @@ -806,11 +818,9 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) } else { trace_esp_error_fifo_overrun(); } - } else if (s->ti_wptr == TI_BUFSZ - 1) { - trace_esp_error_fifo_overrun(); } else { s->ti_size++; - s->ti_buf[s->ti_wptr++] = val & 0xff; + esp_fifo_push(s, val & 0xff); } /* Non-DMA transfers raise an interrupt after every byte */ @@ -839,8 +849,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) case CMD_FLUSH: trace_esp_mem_writeb_cmd_flush(val); /*s->ti_size = 0;*/ - s->ti_wptr = 0; - s->ti_rptr = 0; + fifo8_reset(&s->fifo); break; case CMD_RESET: trace_esp_mem_writeb_cmd_reset(val); @@ -958,11 +967,18 @@ static int esp_pre_save(void *opaque) static int esp_post_load(void *opaque, int version_id) { ESPState *s = ESP(opaque); + int len, i; version_id = MIN(version_id, s->mig_version_id); if (version_id < 5) { esp_set_tc(s, s->mig_dma_left); + + /* Migrate ti_buf to fifo */ + len = s->mig_ti_wptr - s->mig_ti_rptr; + for (i = 0; i < len; i++) { + fifo8_push(&s->fifo, s->mig_ti_buf[i]); + } } s->mig_version_id = vmstate_esp.version_id; @@ -979,9 +995,9 @@ const VMStateDescription vmstate_esp = { VMSTATE_BUFFER(rregs, ESPState), VMSTATE_BUFFER(wregs, ESPState), VMSTATE_INT32(ti_size, ESPState), - VMSTATE_UINT32(ti_rptr, ESPState), - VMSTATE_UINT32(ti_wptr, ESPState), - VMSTATE_BUFFER(ti_buf, ESPState), + VMSTATE_UINT32_TEST(mig_ti_rptr, ESPState, esp_is_before_version_5), + VMSTATE_UINT32_TEST(mig_ti_wptr, ESPState, esp_is_before_version_5), + VMSTATE_BUFFER_TEST(mig_ti_buf, ESPState, esp_is_before_version_5), VMSTATE_UINT32(status, ESPState), VMSTATE_UINT32_TEST(mig_deferred_status, ESPState, esp_is_before_version_5), @@ -995,6 +1011,7 @@ const VMStateDescription vmstate_esp = { VMSTATE_UINT32_TEST(mig_dma_left, ESPState, esp_is_before_version_5), VMSTATE_BOOL_TEST(data_in_ready, ESPState, esp_is_version_5), VMSTATE_UINT8_TEST(cmdbuf_cdb_offset, ESPState, esp_is_version_5), + VMSTATE_FIFO8_TEST(fifo, ESPState, esp_is_version_5), VMSTATE_END_OF_LIST() }, }; @@ -1047,7 +1064,7 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr, break; } dmalen = esp_get_tc(s); - if (dmalen == 0 || (s->ti_wptr == TI_BUFSZ)) { + if (dmalen == 0 || fifo8_is_full(&s->fifo)) { s->pdma_cb(s); } } @@ -1070,9 +1087,7 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr, val = (val << 8) | esp_pdma_read(s); break; } - if (s->ti_rptr == s->ti_wptr) { - s->ti_wptr = 0; - s->ti_rptr = 0; + if (fifo8_is_empty(&s->fifo)) { s->pdma_cb(s); } return val; @@ -1182,6 +1197,20 @@ static const TypeInfo sysbus_esp_info = { .class_init = sysbus_esp_class_init, }; +static void esp_finalize(Object *obj) +{ + ESPState *s = ESP(obj); + + fifo8_destroy(&s->fifo); +} + +static void esp_init(Object *obj) +{ + ESPState *s = ESP(obj); + + fifo8_create(&s->fifo, ESP_FIFO_SZ); +} + static void esp_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1194,6 +1223,8 @@ static void esp_class_init(ObjectClass *klass, void *data) static const TypeInfo esp_info = { .name = TYPE_ESP, .parent = TYPE_DEVICE, + .instance_init = esp_init, + .instance_finalize = esp_finalize, .instance_size = sizeof(ESPState), .class_init = esp_class_init, }; diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h index 6f3bf4a0ce..063d9b1caa 100644 --- a/include/hw/scsi/esp.h +++ b/include/hw/scsi/esp.h @@ -3,6 +3,7 @@ #include "hw/scsi/scsi.h" #include "hw/sysbus.h" +#include "qemu/fifo8.h" #include "qom/object.h" /* esp.c */ @@ -10,7 +11,7 @@ typedef void (*ESPDMAMemoryReadWriteFunc)(void *opaque, uint8_t *buf, int len); #define ESP_REGS 16 -#define TI_BUFSZ 16 +#define ESP_FIFO_SZ 16 #define ESP_CMDBUF_SZ 32 typedef struct ESPState ESPState; @@ -28,10 +29,9 @@ struct ESPState { uint8_t chip_id; bool tchi_written; int32_t ti_size; - uint32_t ti_rptr, ti_wptr; uint32_t status; uint32_t dma; - uint8_t ti_buf[TI_BUFSZ]; + Fifo8 fifo; SCSIBus bus; SCSIDevice *current_dev; SCSIRequest *current_req; @@ -58,6 +58,8 @@ struct ESPState { uint32_t mig_dma_left; uint32_t mig_deferred_status; bool mig_deferred_complete; + uint32_t mig_ti_rptr, mig_ti_wptr; + uint8_t mig_ti_buf[ESP_FIFO_SZ]; }; #define TYPE_SYSBUS_ESP "sysbus-esp"
Rename TI_BUFSZ to ESP_FIFO_SZ since this constant is really describing the size of the FIFO and is not directly related to the TI size. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> --- hw/scsi/esp.c | 117 ++++++++++++++++++++++++++---------------- include/hw/scsi/esp.h | 8 +-- 2 files changed, 79 insertions(+), 46 deletions(-)