[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v2 42/42] esp: add support for unaligned accesses
From: |
Laurent Vivier |
Subject: |
Re: [PATCH v2 42/42] esp: add support for unaligned accesses |
Date: |
Wed, 3 Mar 2021 21:22:49 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.7.0 |
Le 09/02/2021 à 20:30, Mark Cave-Ayland a écrit :
> When the MacOS toolbox ROM transfers data from a target device to an unaligned
> memory address, the first/last byte of a 16-bit transfer needs to be handled
> separately. This means that the first byte is preloaded into the FIFO before
> the transfer, or the last byte remains in the FIFO after the transfer.
>
> The result of this is that the PDMA routines must be updated so that the FIFO
> is loaded/unloaded if the last 16-bit word is used (rather than the last byte)
> and any remaining byte from a FIFO wraparound is handled correctly.
>
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
> hw/scsi/esp.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
> 1 file changed, 41 insertions(+), 7 deletions(-)
>
> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
> index ae9e265a5d..d2d6366525 100644
> --- a/hw/scsi/esp.c
> +++ b/hw/scsi/esp.c
> @@ -498,11 +498,22 @@ static void do_dma_pdma_cb(ESPState *s)
>
> if (to_device) {
> /* Copy FIFO data to device */
> - len = MIN(fifo8_num_used(&s->fifo), ESP_FIFO_SZ);
> + len = MIN(s->async_len, ESP_FIFO_SZ);
> + len = MIN(len, fifo8_num_used(&s->fifo));
> memcpy(s->async_buf, fifo8_pop_buf(&s->fifo, len, &n), len);
> - s->async_buf += len;
> - s->async_len -= len;
> - s->ti_size += len;
> + s->async_buf += n;
> + s->async_len -= n;
> + s->ti_size += n;
> +
> + if (n < len) {
> + /* Unaligned accesses can cause FIFO wraparound */
> + len = len - n;
> + memcpy(s->async_buf, fifo8_pop_buf(&s->fifo, len, &n), len);
> + s->async_buf += n;
> + s->async_len -= n;
> + s->ti_size += n;
> + }
> +
> if (s->async_len == 0) {
> scsi_req_continue(s->current_req);
> return;
> @@ -532,12 +543,18 @@ static void do_dma_pdma_cb(ESPState *s)
>
> if (esp_get_tc(s) != 0) {
> /* Copy device data to FIFO */
> - len = MIN(s->async_len, fifo8_num_free(&s->fifo));
> + len = MIN(s->async_len, esp_get_tc(s));
> + 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;
> esp_set_tc(s, esp_get_tc(s) - len);
> +
> + if (esp_get_tc(s) == 0) {
> + /* Indicate transfer to FIFO is complete */
> + s->rregs[ESP_RSTAT] |= STAT_TC;
> + }
> return;
> }
>
> @@ -612,12 +629,29 @@ static void esp_do_dma(ESPState *s)
> if (s->dma_memory_write) {
> s->dma_memory_write(s->dma_opaque, s->async_buf, len);
> } else {
> + /* Adjust TC for any leftover data in the FIFO */
> + if (!fifo8_is_empty(&s->fifo)) {
> + esp_set_tc(s, esp_get_tc(s) - fifo8_num_used(&s->fifo));
> + }
> +
> /* Copy device data to FIFO */
> 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;
> +
> + /*
> + * MacOS toolbox uses a TI length of 16 bytes for all commands,
> so
> + * commands shorter than this must be padded accordingly
> + */
> + if (len < esp_get_tc(s) && esp_get_tc(s) <= ESP_FIFO_SZ) {
> + while (fifo8_num_used(&s->fifo) < ESP_FIFO_SZ) {
> + esp_fifo_push(s, 0);
> + len++;
> + }
> + }
> +
> esp_set_tc(s, esp_get_tc(s) - len);
> s->pdma_cb = do_dma_pdma_cb;
> esp_raise_drq(s);
> @@ -1168,7 +1202,7 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr
> addr,
> break;
> }
> dmalen = esp_get_tc(s);
> - if (dmalen == 0 || fifo8_is_full(&s->fifo)) {
> + if (dmalen == 0 || fifo8_num_free(&s->fifo) < 2) {
> s->pdma_cb(s);
> }
> }
> @@ -1191,7 +1225,7 @@ static uint64_t sysbus_esp_pdma_read(void *opaque,
> hwaddr addr,
> val = (val << 8) | esp_pdma_read(s);
> break;
> }
> - if (fifo8_is_empty(&s->fifo)) {
> + if (fifo8_num_used(&s->fifo) < 2) {
> s->pdma_cb(s);
> }
> return val;
>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [PATCH v2 42/42] esp: add support for unaligned accesses,
Laurent Vivier <=