esp: raise interrupt after every non-DMA byte transferred to the FIFO
[qemu/ar7.git] / hw / scsi / esp.c
blob4ac299651ffd499af6a6225928518da27f884f57
1 /*
2 * QEMU ESP/NCR53C9x emulation
4 * Copyright (c) 2005-2006 Fabrice Bellard
5 * Copyright (c) 2012 Herve Poussineau
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
26 #include "qemu/osdep.h"
27 #include "hw/sysbus.h"
28 #include "migration/vmstate.h"
29 #include "hw/irq.h"
30 #include "hw/scsi/esp.h"
31 #include "trace.h"
32 #include "qemu/log.h"
33 #include "qemu/module.h"
36 * On Sparc32, this is the ESP (NCR53C90) part of chip STP2000 (Master I/O),
37 * also produced as NCR89C100. See
38 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
39 * and
40 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
42 * On Macintosh Quadra it is a NCR53C96.
45 static void esp_raise_irq(ESPState *s)
47 if (!(s->rregs[ESP_RSTAT] & STAT_INT)) {
48 s->rregs[ESP_RSTAT] |= STAT_INT;
49 qemu_irq_raise(s->irq);
50 trace_esp_raise_irq();
54 static void esp_lower_irq(ESPState *s)
56 if (s->rregs[ESP_RSTAT] & STAT_INT) {
57 s->rregs[ESP_RSTAT] &= ~STAT_INT;
58 qemu_irq_lower(s->irq);
59 trace_esp_lower_irq();
63 static void esp_raise_drq(ESPState *s)
65 qemu_irq_raise(s->irq_data);
66 trace_esp_raise_drq();
69 static void esp_lower_drq(ESPState *s)
71 qemu_irq_lower(s->irq_data);
72 trace_esp_lower_drq();
75 void esp_dma_enable(ESPState *s, int irq, int level)
77 if (level) {
78 s->dma_enabled = 1;
79 trace_esp_dma_enable();
80 if (s->dma_cb) {
81 s->dma_cb(s);
82 s->dma_cb = NULL;
84 } else {
85 trace_esp_dma_disable();
86 s->dma_enabled = 0;
90 void esp_request_cancelled(SCSIRequest *req)
92 ESPState *s = req->hba_private;
94 if (req == s->current_req) {
95 scsi_req_unref(s->current_req);
96 s->current_req = NULL;
97 s->current_dev = NULL;
101 static uint32_t esp_get_tc(ESPState *s)
103 uint32_t dmalen;
105 dmalen = s->rregs[ESP_TCLO];
106 dmalen |= s->rregs[ESP_TCMID] << 8;
107 dmalen |= s->rregs[ESP_TCHI] << 16;
109 return dmalen;
112 static void esp_set_tc(ESPState *s, uint32_t dmalen)
114 s->rregs[ESP_TCLO] = dmalen;
115 s->rregs[ESP_TCMID] = dmalen >> 8;
116 s->rregs[ESP_TCHI] = dmalen >> 16;
119 static uint32_t esp_get_stc(ESPState *s)
121 uint32_t dmalen;
123 dmalen = s->wregs[ESP_TCLO];
124 dmalen |= s->wregs[ESP_TCMID] << 8;
125 dmalen |= s->wregs[ESP_TCHI] << 16;
127 return dmalen;
130 static uint8_t esp_pdma_read(ESPState *s)
132 uint8_t val;
134 if (s->do_cmd) {
135 val = s->cmdbuf[s->cmdlen++];
136 } else {
137 val = s->ti_buf[s->ti_rptr++];
140 return val;
143 static void esp_pdma_write(ESPState *s, uint8_t val)
145 uint32_t dmalen = esp_get_tc(s);
147 if (dmalen == 0) {
148 return;
151 if (s->do_cmd) {
152 s->cmdbuf[s->cmdlen++] = val;
153 } else {
154 s->ti_buf[s->ti_wptr++] = val;
157 dmalen--;
158 esp_set_tc(s, dmalen);
161 static int esp_select(ESPState *s)
163 int target;
165 target = s->wregs[ESP_WBUSID] & BUSID_DID;
167 s->ti_size = 0;
168 s->ti_rptr = 0;
169 s->ti_wptr = 0;
171 if (s->current_req) {
172 /* Started a new command before the old one finished. Cancel it. */
173 scsi_req_cancel(s->current_req);
174 s->async_len = 0;
177 s->current_dev = scsi_device_find(&s->bus, 0, target, 0);
178 if (!s->current_dev) {
179 /* No such drive */
180 s->rregs[ESP_RSTAT] = 0;
181 s->rregs[ESP_RINTR] |= INTR_DC;
182 s->rregs[ESP_RSEQ] = SEQ_0;
183 esp_raise_irq(s);
184 return -1;
188 * Note that we deliberately don't raise the IRQ here: this will be done
189 * either in do_busid_cmd() for DATA OUT transfers or by the deferred
190 * IRQ mechanism in esp_transfer_data() for DATA IN transfers
192 s->rregs[ESP_RINTR] |= INTR_FC;
193 s->rregs[ESP_RSEQ] = SEQ_CD;
194 return 0;
197 static uint32_t get_cmd(ESPState *s)
199 uint8_t *buf = s->cmdbuf;
200 uint32_t dmalen;
201 int target;
203 target = s->wregs[ESP_WBUSID] & BUSID_DID;
204 if (s->dma) {
205 dmalen = esp_get_tc(s);
206 if (dmalen > ESP_CMDBUF_SZ) {
207 return 0;
209 if (s->dma_memory_read) {
210 s->dma_memory_read(s->dma_opaque, buf, dmalen);
211 } else {
212 if (esp_select(s) < 0) {
213 return -1;
215 esp_raise_drq(s);
216 return 0;
218 } else {
219 dmalen = s->ti_size;
220 if (dmalen > TI_BUFSZ) {
221 return 0;
223 memcpy(buf, s->ti_buf, dmalen);
224 buf[0] = buf[2] >> 5;
226 trace_esp_get_cmd(dmalen, target);
228 if (esp_select(s) < 0) {
229 return -1;
231 return dmalen;
234 static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
236 int32_t datalen;
237 int lun;
238 SCSIDevice *current_lun;
240 trace_esp_do_busid_cmd(busid);
241 lun = busid & 7;
242 current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, lun);
243 s->current_req = scsi_req_new(current_lun, 0, lun, buf, s);
244 datalen = scsi_req_enqueue(s->current_req);
245 s->ti_size = datalen;
246 if (datalen != 0) {
247 s->rregs[ESP_RSTAT] = STAT_TC;
248 s->rregs[ESP_RSEQ] = SEQ_CD;
249 esp_set_tc(s, 0);
250 if (datalen > 0) {
252 * Switch to DATA IN phase but wait until initial data xfer is
253 * complete before raising the command completion interrupt
255 s->data_in_ready = false;
256 s->rregs[ESP_RSTAT] |= STAT_DI;
257 } else {
258 s->rregs[ESP_RSTAT] |= STAT_DO;
259 s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
260 esp_raise_irq(s);
261 esp_lower_drq(s);
263 scsi_req_continue(s->current_req);
264 return;
268 static void do_cmd(ESPState *s)
270 uint8_t *buf = s->cmdbuf;
271 uint8_t busid = buf[0];
273 do_busid_cmd(s, &buf[1], busid);
276 static void satn_pdma_cb(ESPState *s)
278 s->do_cmd = 0;
279 if (s->cmdlen) {
280 do_cmd(s);
284 static void handle_satn(ESPState *s)
286 int32_t cmdlen;
288 if (s->dma && !s->dma_enabled) {
289 s->dma_cb = handle_satn;
290 return;
292 s->pdma_cb = satn_pdma_cb;
293 cmdlen = get_cmd(s);
294 if (cmdlen > 0) {
295 s->cmdlen = cmdlen;
296 do_cmd(s);
297 } else if (cmdlen == 0) {
298 s->cmdlen = 0;
299 s->do_cmd = 1;
300 /* Target present, but no cmd yet - switch to command phase */
301 s->rregs[ESP_RSEQ] = SEQ_CD;
302 s->rregs[ESP_RSTAT] = STAT_CD;
306 static void s_without_satn_pdma_cb(ESPState *s)
308 s->do_cmd = 0;
309 if (s->cmdlen) {
310 do_busid_cmd(s, s->cmdbuf, 0);
314 static void handle_s_without_atn(ESPState *s)
316 int32_t cmdlen;
318 if (s->dma && !s->dma_enabled) {
319 s->dma_cb = handle_s_without_atn;
320 return;
322 s->pdma_cb = s_without_satn_pdma_cb;
323 cmdlen = get_cmd(s);
324 if (cmdlen > 0) {
325 s->cmdlen = cmdlen;
326 do_busid_cmd(s, s->cmdbuf, 0);
327 } else if (cmdlen == 0) {
328 s->cmdlen = 0;
329 s->do_cmd = 1;
330 /* Target present, but no cmd yet - switch to command phase */
331 s->rregs[ESP_RSEQ] = SEQ_CD;
332 s->rregs[ESP_RSTAT] = STAT_CD;
336 static void satn_stop_pdma_cb(ESPState *s)
338 s->do_cmd = 0;
339 if (s->cmdlen) {
340 trace_esp_handle_satn_stop(s->cmdlen);
341 s->do_cmd = 1;
342 s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
343 s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
344 s->rregs[ESP_RSEQ] = SEQ_CD;
345 esp_raise_irq(s);
349 static void handle_satn_stop(ESPState *s)
351 int32_t cmdlen;
353 if (s->dma && !s->dma_enabled) {
354 s->dma_cb = handle_satn_stop;
355 return;
357 s->pdma_cb = satn_stop_pdma_cb;
358 cmdlen = get_cmd(s);
359 if (cmdlen > 0) {
360 trace_esp_handle_satn_stop(s->cmdlen);
361 s->cmdlen = cmdlen;
362 s->do_cmd = 1;
363 s->rregs[ESP_RSTAT] = STAT_CD;
364 s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
365 s->rregs[ESP_RSEQ] = SEQ_CD;
366 esp_raise_irq(s);
367 } else if (cmdlen == 0) {
368 s->cmdlen = 0;
369 s->do_cmd = 1;
370 /* Target present, but no cmd yet - switch to command phase */
371 s->rregs[ESP_RSEQ] = SEQ_CD;
372 s->rregs[ESP_RSTAT] = STAT_CD;
376 static void write_response_pdma_cb(ESPState *s)
378 s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
379 s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
380 s->rregs[ESP_RSEQ] = SEQ_CD;
381 esp_raise_irq(s);
384 static void write_response(ESPState *s)
386 trace_esp_write_response(s->status);
387 s->ti_buf[0] = s->status;
388 s->ti_buf[1] = 0;
389 if (s->dma) {
390 if (s->dma_memory_write) {
391 s->dma_memory_write(s->dma_opaque, s->ti_buf, 2);
392 s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
393 s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
394 s->rregs[ESP_RSEQ] = SEQ_CD;
395 } else {
396 s->pdma_cb = write_response_pdma_cb;
397 esp_raise_drq(s);
398 return;
400 } else {
401 s->ti_size = 2;
402 s->ti_rptr = 0;
403 s->ti_wptr = 2;
404 s->rregs[ESP_RFLAGS] = 2;
406 esp_raise_irq(s);
409 static void esp_dma_done(ESPState *s)
411 s->rregs[ESP_RSTAT] |= STAT_TC;
412 s->rregs[ESP_RINTR] |= INTR_BS;
413 s->rregs[ESP_RSEQ] = 0;
414 s->rregs[ESP_RFLAGS] = 0;
415 esp_set_tc(s, 0);
416 esp_raise_irq(s);
419 static void do_dma_pdma_cb(ESPState *s)
421 int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
422 int len;
424 if (s->do_cmd) {
425 s->ti_size = 0;
426 s->cmdlen = 0;
427 s->do_cmd = 0;
428 do_cmd(s);
429 esp_lower_drq(s);
430 return;
433 if (to_device) {
434 /* Copy FIFO data to device */
435 len = MIN(s->ti_wptr, TI_BUFSZ);
436 memcpy(s->async_buf, s->ti_buf, len);
437 s->ti_wptr = 0;
438 s->ti_rptr = 0;
439 s->async_buf += len;
440 s->async_len -= len;
441 s->ti_size += len;
442 if (s->async_len == 0) {
443 scsi_req_continue(s->current_req);
444 return;
447 if (esp_get_tc(s) == 0) {
448 esp_lower_drq(s);
449 esp_dma_done(s);
452 return;
453 } else {
454 if (s->async_len == 0) {
455 if (s->current_req) {
456 /* Defer until the scsi layer has completed */
457 scsi_req_continue(s->current_req);
458 s->data_in_ready = false;
460 return;
463 if (esp_get_tc(s) != 0) {
464 /* Copy device data to FIFO */
465 s->ti_wptr = 0;
466 s->ti_rptr = 0;
467 len = MIN(s->async_len, TI_BUFSZ);
468 memcpy(s->ti_buf, s->async_buf, len);
469 s->ti_wptr += len;
470 s->async_buf += len;
471 s->async_len -= len;
472 s->ti_size -= len;
473 esp_set_tc(s, esp_get_tc(s) - len);
474 return;
477 /* Partially filled a scsi buffer. Complete immediately. */
478 esp_lower_drq(s);
479 esp_dma_done(s);
483 static void esp_do_dma(ESPState *s)
485 uint32_t len;
486 int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
488 len = esp_get_tc(s);
489 if (s->do_cmd) {
491 * handle_ti_cmd() case: esp_do_dma() is called only from
492 * handle_ti_cmd() with do_cmd != NULL (see the assert())
494 trace_esp_do_dma(s->cmdlen, len);
495 assert(s->cmdlen <= sizeof(s->cmdbuf) &&
496 len <= sizeof(s->cmdbuf) - s->cmdlen);
497 if (s->dma_memory_read) {
498 s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
499 } else {
500 s->pdma_cb = do_dma_pdma_cb;
501 esp_raise_drq(s);
502 return;
504 trace_esp_handle_ti_cmd(s->cmdlen);
505 s->ti_size = 0;
506 s->cmdlen = 0;
507 s->do_cmd = 0;
508 do_cmd(s);
509 return;
511 if (s->async_len == 0) {
512 /* Defer until data is available. */
513 return;
515 if (len > s->async_len) {
516 len = s->async_len;
518 if (to_device) {
519 if (s->dma_memory_read) {
520 s->dma_memory_read(s->dma_opaque, s->async_buf, len);
521 } else {
522 s->pdma_cb = do_dma_pdma_cb;
523 esp_raise_drq(s);
524 return;
526 } else {
527 if (s->dma_memory_write) {
528 s->dma_memory_write(s->dma_opaque, s->async_buf, len);
529 } else {
530 /* Copy device data to FIFO */
531 len = MIN(len, TI_BUFSZ - s->ti_wptr);
532 memcpy(&s->ti_buf[s->ti_wptr], s->async_buf, len);
533 s->ti_wptr += len;
534 s->async_buf += len;
535 s->async_len -= len;
536 s->ti_size -= len;
537 esp_set_tc(s, esp_get_tc(s) - len);
538 s->pdma_cb = do_dma_pdma_cb;
539 esp_raise_drq(s);
541 /* Indicate transfer to FIFO is complete */
542 s->rregs[ESP_RSTAT] |= STAT_TC;
543 return;
546 esp_set_tc(s, esp_get_tc(s) - len);
547 s->async_buf += len;
548 s->async_len -= len;
549 if (to_device) {
550 s->ti_size += len;
551 } else {
552 s->ti_size -= len;
554 if (s->async_len == 0) {
555 scsi_req_continue(s->current_req);
557 * If there is still data to be read from the device then
558 * complete the DMA operation immediately. Otherwise defer
559 * until the scsi layer has completed.
561 if (to_device || esp_get_tc(s) != 0 || s->ti_size == 0) {
562 return;
566 /* Partially filled a scsi buffer. Complete immediately. */
567 esp_dma_done(s);
568 esp_lower_drq(s);
571 void esp_command_complete(SCSIRequest *req, size_t resid)
573 ESPState *s = req->hba_private;
575 trace_esp_command_complete();
576 if (s->ti_size != 0) {
577 trace_esp_command_complete_unexpected();
579 s->ti_size = 0;
580 s->async_len = 0;
581 if (req->status) {
582 trace_esp_command_complete_fail();
584 s->status = req->status;
585 s->rregs[ESP_RSTAT] = STAT_ST;
586 esp_dma_done(s);
587 esp_lower_drq(s);
588 if (s->current_req) {
589 scsi_req_unref(s->current_req);
590 s->current_req = NULL;
591 s->current_dev = NULL;
595 void esp_transfer_data(SCSIRequest *req, uint32_t len)
597 ESPState *s = req->hba_private;
598 int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
599 uint32_t dmalen = esp_get_tc(s);
601 assert(!s->do_cmd);
602 trace_esp_transfer_data(dmalen, s->ti_size);
603 s->async_len = len;
604 s->async_buf = scsi_req_get_buf(req);
606 if (!to_device && !s->data_in_ready) {
608 * Initial incoming data xfer is complete so raise command
609 * completion interrupt
611 s->data_in_ready = true;
612 s->rregs[ESP_RSTAT] |= STAT_TC;
613 s->rregs[ESP_RINTR] |= INTR_BS;
614 esp_raise_irq(s);
617 * If data is ready to transfer and the TI command has already
618 * been executed, start DMA immediately. Otherwise DMA will start
619 * when host sends the TI command
621 if (s->ti_size && (s->rregs[ESP_CMD] == (CMD_TI | CMD_DMA))) {
622 esp_do_dma(s);
624 return;
627 if (dmalen) {
628 esp_do_dma(s);
629 } else if (s->ti_size <= 0) {
631 * If this was the last part of a DMA transfer then the
632 * completion interrupt is deferred to here.
634 esp_dma_done(s);
635 esp_lower_drq(s);
639 static void handle_ti(ESPState *s)
641 uint32_t dmalen;
643 if (s->dma && !s->dma_enabled) {
644 s->dma_cb = handle_ti;
645 return;
648 dmalen = esp_get_tc(s);
649 if (s->dma) {
650 trace_esp_handle_ti(dmalen);
651 s->rregs[ESP_RSTAT] &= ~STAT_TC;
652 esp_do_dma(s);
653 } else if (s->do_cmd) {
654 trace_esp_handle_ti_cmd(s->cmdlen);
655 s->ti_size = 0;
656 s->cmdlen = 0;
657 s->do_cmd = 0;
658 do_cmd(s);
662 void esp_hard_reset(ESPState *s)
664 memset(s->rregs, 0, ESP_REGS);
665 memset(s->wregs, 0, ESP_REGS);
666 s->tchi_written = 0;
667 s->ti_size = 0;
668 s->ti_rptr = 0;
669 s->ti_wptr = 0;
670 s->dma = 0;
671 s->do_cmd = 0;
672 s->dma_cb = NULL;
674 s->rregs[ESP_CFG1] = 7;
677 static void esp_soft_reset(ESPState *s)
679 qemu_irq_lower(s->irq);
680 qemu_irq_lower(s->irq_data);
681 esp_hard_reset(s);
684 static void parent_esp_reset(ESPState *s, int irq, int level)
686 if (level) {
687 esp_soft_reset(s);
691 uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
693 uint32_t val;
695 switch (saddr) {
696 case ESP_FIFO:
697 if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
698 /* Data out. */
699 qemu_log_mask(LOG_UNIMP, "esp: PIO data read not implemented\n");
700 s->rregs[ESP_FIFO] = 0;
701 } else if (s->ti_rptr < s->ti_wptr) {
702 s->ti_size--;
703 s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
705 if (s->ti_rptr == s->ti_wptr) {
706 s->ti_rptr = 0;
707 s->ti_wptr = 0;
709 val = s->rregs[ESP_FIFO];
710 break;
711 case ESP_RINTR:
713 * Clear sequence step, interrupt register and all status bits
714 * except TC
716 val = s->rregs[ESP_RINTR];
717 s->rregs[ESP_RINTR] = 0;
718 s->rregs[ESP_RSTAT] &= ~STAT_TC;
719 s->rregs[ESP_RSEQ] = SEQ_0;
720 esp_lower_irq(s);
721 break;
722 case ESP_TCHI:
723 /* Return the unique id if the value has never been written */
724 if (!s->tchi_written) {
725 val = s->chip_id;
726 } else {
727 val = s->rregs[saddr];
729 break;
730 default:
731 val = s->rregs[saddr];
732 break;
735 trace_esp_mem_readb(saddr, val);
736 return val;
739 void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
741 trace_esp_mem_writeb(saddr, s->wregs[saddr], val);
742 switch (saddr) {
743 case ESP_TCHI:
744 s->tchi_written = true;
745 /* fall through */
746 case ESP_TCLO:
747 case ESP_TCMID:
748 s->rregs[ESP_RSTAT] &= ~STAT_TC;
749 break;
750 case ESP_FIFO:
751 if (s->do_cmd) {
752 if (s->cmdlen < ESP_CMDBUF_SZ) {
753 s->cmdbuf[s->cmdlen++] = val & 0xff;
754 } else {
755 trace_esp_error_fifo_overrun();
757 } else if (s->ti_wptr == TI_BUFSZ - 1) {
758 trace_esp_error_fifo_overrun();
759 } else {
760 s->ti_size++;
761 s->ti_buf[s->ti_wptr++] = val & 0xff;
764 /* Non-DMA transfers raise an interrupt after every byte */
765 if (s->rregs[ESP_CMD] == CMD_TI) {
766 s->rregs[ESP_RINTR] |= INTR_FC | INTR_BS;
767 esp_raise_irq(s);
769 break;
770 case ESP_CMD:
771 s->rregs[saddr] = val;
772 if (val & CMD_DMA) {
773 s->dma = 1;
774 /* Reload DMA counter. */
775 if (esp_get_stc(s) == 0) {
776 esp_set_tc(s, 0x10000);
777 } else {
778 esp_set_tc(s, esp_get_stc(s));
780 } else {
781 s->dma = 0;
783 switch (val & CMD_CMD) {
784 case CMD_NOP:
785 trace_esp_mem_writeb_cmd_nop(val);
786 break;
787 case CMD_FLUSH:
788 trace_esp_mem_writeb_cmd_flush(val);
789 /*s->ti_size = 0;*/
790 s->ti_wptr = 0;
791 s->ti_rptr = 0;
792 break;
793 case CMD_RESET:
794 trace_esp_mem_writeb_cmd_reset(val);
795 esp_soft_reset(s);
796 break;
797 case CMD_BUSRESET:
798 trace_esp_mem_writeb_cmd_bus_reset(val);
799 if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
800 s->rregs[ESP_RINTR] |= INTR_RST;
801 esp_raise_irq(s);
803 break;
804 case CMD_TI:
805 trace_esp_mem_writeb_cmd_ti(val);
806 handle_ti(s);
807 break;
808 case CMD_ICCS:
809 trace_esp_mem_writeb_cmd_iccs(val);
810 write_response(s);
811 s->rregs[ESP_RINTR] |= INTR_FC;
812 s->rregs[ESP_RSTAT] |= STAT_MI;
813 break;
814 case CMD_MSGACC:
815 trace_esp_mem_writeb_cmd_msgacc(val);
816 s->rregs[ESP_RINTR] |= INTR_DC;
817 s->rregs[ESP_RSEQ] = 0;
818 s->rregs[ESP_RFLAGS] = 0;
819 esp_raise_irq(s);
820 break;
821 case CMD_PAD:
822 trace_esp_mem_writeb_cmd_pad(val);
823 s->rregs[ESP_RSTAT] = STAT_TC;
824 s->rregs[ESP_RINTR] |= INTR_FC;
825 s->rregs[ESP_RSEQ] = 0;
826 break;
827 case CMD_SATN:
828 trace_esp_mem_writeb_cmd_satn(val);
829 break;
830 case CMD_RSTATN:
831 trace_esp_mem_writeb_cmd_rstatn(val);
832 break;
833 case CMD_SEL:
834 trace_esp_mem_writeb_cmd_sel(val);
835 handle_s_without_atn(s);
836 break;
837 case CMD_SELATN:
838 trace_esp_mem_writeb_cmd_selatn(val);
839 handle_satn(s);
840 break;
841 case CMD_SELATNS:
842 trace_esp_mem_writeb_cmd_selatns(val);
843 handle_satn_stop(s);
844 break;
845 case CMD_ENSEL:
846 trace_esp_mem_writeb_cmd_ensel(val);
847 s->rregs[ESP_RINTR] = 0;
848 break;
849 case CMD_DISSEL:
850 trace_esp_mem_writeb_cmd_dissel(val);
851 s->rregs[ESP_RINTR] = 0;
852 esp_raise_irq(s);
853 break;
854 default:
855 trace_esp_error_unhandled_command(val);
856 break;
858 break;
859 case ESP_WBUSID ... ESP_WSYNO:
860 break;
861 case ESP_CFG1:
862 case ESP_CFG2: case ESP_CFG3:
863 case ESP_RES3: case ESP_RES4:
864 s->rregs[saddr] = val;
865 break;
866 case ESP_WCCF ... ESP_WTEST:
867 break;
868 default:
869 trace_esp_error_invalid_write(val, saddr);
870 return;
872 s->wregs[saddr] = val;
875 static bool esp_mem_accepts(void *opaque, hwaddr addr,
876 unsigned size, bool is_write,
877 MemTxAttrs attrs)
879 return (size == 1) || (is_write && size == 4);
882 static bool esp_is_before_version_5(void *opaque, int version_id)
884 ESPState *s = ESP(opaque);
886 version_id = MIN(version_id, s->mig_version_id);
887 return version_id < 5;
890 static bool esp_is_version_5(void *opaque, int version_id)
892 ESPState *s = ESP(opaque);
894 version_id = MIN(version_id, s->mig_version_id);
895 return version_id == 5;
898 static int esp_pre_save(void *opaque)
900 ESPState *s = ESP(opaque);
902 s->mig_version_id = vmstate_esp.version_id;
903 return 0;
906 static int esp_post_load(void *opaque, int version_id)
908 ESPState *s = ESP(opaque);
910 version_id = MIN(version_id, s->mig_version_id);
912 if (version_id < 5) {
913 esp_set_tc(s, s->mig_dma_left);
916 s->mig_version_id = vmstate_esp.version_id;
917 return 0;
920 const VMStateDescription vmstate_esp = {
921 .name = "esp",
922 .version_id = 5,
923 .minimum_version_id = 3,
924 .pre_save = esp_pre_save,
925 .post_load = esp_post_load,
926 .fields = (VMStateField[]) {
927 VMSTATE_BUFFER(rregs, ESPState),
928 VMSTATE_BUFFER(wregs, ESPState),
929 VMSTATE_INT32(ti_size, ESPState),
930 VMSTATE_UINT32(ti_rptr, ESPState),
931 VMSTATE_UINT32(ti_wptr, ESPState),
932 VMSTATE_BUFFER(ti_buf, ESPState),
933 VMSTATE_UINT32(status, ESPState),
934 VMSTATE_UINT32_TEST(mig_deferred_status, ESPState,
935 esp_is_before_version_5),
936 VMSTATE_BOOL_TEST(mig_deferred_complete, ESPState,
937 esp_is_before_version_5),
938 VMSTATE_UINT32(dma, ESPState),
939 VMSTATE_PARTIAL_BUFFER(cmdbuf, ESPState, 16),
940 VMSTATE_BUFFER_START_MIDDLE_V(cmdbuf, ESPState, 16, 4),
941 VMSTATE_UINT32(cmdlen, ESPState),
942 VMSTATE_UINT32(do_cmd, ESPState),
943 VMSTATE_UINT32_TEST(mig_dma_left, ESPState, esp_is_before_version_5),
944 VMSTATE_BOOL_TEST(data_in_ready, ESPState, esp_is_version_5),
945 VMSTATE_END_OF_LIST()
949 static void sysbus_esp_mem_write(void *opaque, hwaddr addr,
950 uint64_t val, unsigned int size)
952 SysBusESPState *sysbus = opaque;
953 ESPState *s = ESP(&sysbus->esp);
954 uint32_t saddr;
956 saddr = addr >> sysbus->it_shift;
957 esp_reg_write(s, saddr, val);
960 static uint64_t sysbus_esp_mem_read(void *opaque, hwaddr addr,
961 unsigned int size)
963 SysBusESPState *sysbus = opaque;
964 ESPState *s = ESP(&sysbus->esp);
965 uint32_t saddr;
967 saddr = addr >> sysbus->it_shift;
968 return esp_reg_read(s, saddr);
971 static const MemoryRegionOps sysbus_esp_mem_ops = {
972 .read = sysbus_esp_mem_read,
973 .write = sysbus_esp_mem_write,
974 .endianness = DEVICE_NATIVE_ENDIAN,
975 .valid.accepts = esp_mem_accepts,
978 static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
979 uint64_t val, unsigned int size)
981 SysBusESPState *sysbus = opaque;
982 ESPState *s = ESP(&sysbus->esp);
983 uint32_t dmalen;
985 trace_esp_pdma_write(size);
987 switch (size) {
988 case 1:
989 esp_pdma_write(s, val);
990 break;
991 case 2:
992 esp_pdma_write(s, val >> 8);
993 esp_pdma_write(s, val);
994 break;
996 dmalen = esp_get_tc(s);
997 if (dmalen == 0 || (s->ti_wptr == TI_BUFSZ)) {
998 s->pdma_cb(s);
1002 static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr,
1003 unsigned int size)
1005 SysBusESPState *sysbus = opaque;
1006 ESPState *s = ESP(&sysbus->esp);
1007 uint64_t val = 0;
1009 trace_esp_pdma_read(size);
1011 switch (size) {
1012 case 1:
1013 val = esp_pdma_read(s);
1014 break;
1015 case 2:
1016 val = esp_pdma_read(s);
1017 val = (val << 8) | esp_pdma_read(s);
1018 break;
1020 if (s->ti_rptr == s->ti_wptr) {
1021 s->ti_wptr = 0;
1022 s->ti_rptr = 0;
1023 s->pdma_cb(s);
1025 return val;
1028 static const MemoryRegionOps sysbus_esp_pdma_ops = {
1029 .read = sysbus_esp_pdma_read,
1030 .write = sysbus_esp_pdma_write,
1031 .endianness = DEVICE_NATIVE_ENDIAN,
1032 .valid.min_access_size = 1,
1033 .valid.max_access_size = 4,
1034 .impl.min_access_size = 1,
1035 .impl.max_access_size = 2,
1038 static const struct SCSIBusInfo esp_scsi_info = {
1039 .tcq = false,
1040 .max_target = ESP_MAX_DEVS,
1041 .max_lun = 7,
1043 .transfer_data = esp_transfer_data,
1044 .complete = esp_command_complete,
1045 .cancel = esp_request_cancelled
1048 static void sysbus_esp_gpio_demux(void *opaque, int irq, int level)
1050 SysBusESPState *sysbus = SYSBUS_ESP(opaque);
1051 ESPState *s = ESP(&sysbus->esp);
1053 switch (irq) {
1054 case 0:
1055 parent_esp_reset(s, irq, level);
1056 break;
1057 case 1:
1058 esp_dma_enable(opaque, irq, level);
1059 break;
1063 static void sysbus_esp_realize(DeviceState *dev, Error **errp)
1065 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
1066 SysBusESPState *sysbus = SYSBUS_ESP(dev);
1067 ESPState *s = ESP(&sysbus->esp);
1069 if (!qdev_realize(DEVICE(s), NULL, errp)) {
1070 return;
1073 sysbus_init_irq(sbd, &s->irq);
1074 sysbus_init_irq(sbd, &s->irq_data);
1075 assert(sysbus->it_shift != -1);
1077 s->chip_id = TCHI_FAS100A;
1078 memory_region_init_io(&sysbus->iomem, OBJECT(sysbus), &sysbus_esp_mem_ops,
1079 sysbus, "esp-regs", ESP_REGS << sysbus->it_shift);
1080 sysbus_init_mmio(sbd, &sysbus->iomem);
1081 memory_region_init_io(&sysbus->pdma, OBJECT(sysbus), &sysbus_esp_pdma_ops,
1082 sysbus, "esp-pdma", 4);
1083 sysbus_init_mmio(sbd, &sysbus->pdma);
1085 qdev_init_gpio_in(dev, sysbus_esp_gpio_demux, 2);
1087 scsi_bus_new(&s->bus, sizeof(s->bus), dev, &esp_scsi_info, NULL);
1090 static void sysbus_esp_hard_reset(DeviceState *dev)
1092 SysBusESPState *sysbus = SYSBUS_ESP(dev);
1093 ESPState *s = ESP(&sysbus->esp);
1095 esp_hard_reset(s);
1098 static void sysbus_esp_init(Object *obj)
1100 SysBusESPState *sysbus = SYSBUS_ESP(obj);
1102 object_initialize_child(obj, "esp", &sysbus->esp, TYPE_ESP);
1105 static const VMStateDescription vmstate_sysbus_esp_scsi = {
1106 .name = "sysbusespscsi",
1107 .version_id = 2,
1108 .minimum_version_id = 1,
1109 .fields = (VMStateField[]) {
1110 VMSTATE_UINT8_V(esp.mig_version_id, SysBusESPState, 2),
1111 VMSTATE_STRUCT(esp, SysBusESPState, 0, vmstate_esp, ESPState),
1112 VMSTATE_END_OF_LIST()
1116 static void sysbus_esp_class_init(ObjectClass *klass, void *data)
1118 DeviceClass *dc = DEVICE_CLASS(klass);
1120 dc->realize = sysbus_esp_realize;
1121 dc->reset = sysbus_esp_hard_reset;
1122 dc->vmsd = &vmstate_sysbus_esp_scsi;
1123 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
1126 static const TypeInfo sysbus_esp_info = {
1127 .name = TYPE_SYSBUS_ESP,
1128 .parent = TYPE_SYS_BUS_DEVICE,
1129 .instance_init = sysbus_esp_init,
1130 .instance_size = sizeof(SysBusESPState),
1131 .class_init = sysbus_esp_class_init,
1134 static void esp_class_init(ObjectClass *klass, void *data)
1136 DeviceClass *dc = DEVICE_CLASS(klass);
1138 /* internal device for sysbusesp/pciespscsi, not user-creatable */
1139 dc->user_creatable = false;
1140 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
1143 static const TypeInfo esp_info = {
1144 .name = TYPE_ESP,
1145 .parent = TYPE_DEVICE,
1146 .instance_size = sizeof(ESPState),
1147 .class_init = esp_class_init,
1150 static void esp_register_types(void)
1152 type_register_static(&sysbus_esp_info);
1153 type_register_static(&esp_info);
1156 type_init(esp_register_types)