(linenum→info "unix/slp.c:2238")

qemu/0.9.1/hw/esp.c

    1: /*
    2:  * QEMU ESP/NCR53C9x emulation
    3:  *
    4:  * Copyright (c) 2005-2006 Fabrice Bellard
    5:  *
    6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
    7:  * of this software and associated documentation files (the "Software"), to deal
    8:  * in the Software without restriction, including without limitation the rights
    9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   10:  * copies of the Software, and to permit persons to whom the Software is
   11:  * furnished to do so, subject to the following conditions:
   12:  *
   13:  * The above copyright notice and this permission notice shall be included in
   14:  * all copies or substantial portions of the Software.
   15:  *
   16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   22:  * THE SOFTWARE.
   23:  */
   24: #include "hw.h"
   25: #include "block.h"
   26: #include "scsi-disk.h"
   27: #include "sun4m.h"
   28: /* FIXME: Only needed for MAX_DISKS, which is probably wrong.  */
   29: #include "sysemu.h"
   30: 
   31: /* debug ESP card */
   32: //#define DEBUG_ESP
   33: 
   34: /*
   35:  * On Sparc32, this is the ESP (NCR53C90) part of chip STP2000 (Master I/O),
   36:  * also produced as NCR89C100. See
   37:  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
   38:  * and
   39:  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
   40:  */
   41: 
   42: #ifdef DEBUG_ESP
   43: #define DPRINTF(fmt, args...) \
   44: do { printf("ESP: " fmt , ##args); } while (0)
   45: #else
   46: #define DPRINTF(fmt, args...)
   47: #endif
   48: 
   49: #define ESP_MASK 0x3f
   50: #define ESP_REGS 16
   51: #define ESP_SIZE (ESP_REGS * 4)
   52: #define TI_BUFSZ 32
   53: 
   54: typedef struct ESPState ESPState;
   55: 
   56: struct ESPState {
   57:     qemu_irq irq;
   58:     uint8_t rregs[ESP_REGS];
   59:     uint8_t wregs[ESP_REGS];
   60:     int32_t ti_size;
   61:     uint32_t ti_rptr, ti_wptr;
   62:     uint8_t ti_buf[TI_BUFSZ];
   63:     int sense;
   64:     int dma;
   65:     SCSIDevice *scsi_dev[ESP_MAX_DEVS];
   66:     SCSIDevice *current_dev;
   67:     uint8_t cmdbuf[TI_BUFSZ];
   68:     int cmdlen;
   69:     int do_cmd;
   70: 
   71:     /* The amount of data left in the current DMA transfer.  */
   72:     uint32_t dma_left;
   73:     /* The size of the current DMA transfer.  Zero if no transfer is in
   74:        progress.  */
   75:     uint32_t dma_counter;
   76:     uint8_t *async_buf;
   77:     uint32_t async_len;
   78:     void *dma_opaque;
   79: };
   80: 
   81: #define ESP_TCLO   0x0
   82: #define ESP_TCMID  0x1
   83: #define ESP_FIFO   0x2
   84: #define ESP_CMD    0x3
   85: #define ESP_RSTAT  0x4
   86: #define ESP_WBUSID 0x4
   87: #define ESP_RINTR  0x5
   88: #define ESP_WSEL   0x5
   89: #define ESP_RSEQ   0x6
   90: #define ESP_WSYNTP 0x6
   91: #define ESP_RFLAGS 0x7
   92: #define ESP_WSYNO  0x7
   93: #define ESP_CFG1   0x8
   94: #define ESP_RRES1  0x9
   95: #define ESP_WCCF   0x9
   96: #define ESP_RRES2  0xa
   97: #define ESP_WTEST  0xa
   98: #define ESP_CFG2   0xb
   99: #define ESP_CFG3   0xc
  100: #define ESP_RES3   0xd
  101: #define ESP_TCHI   0xe
  102: #define ESP_RES4   0xf
  103: 
  104: #define CMD_DMA 0x80
  105: #define CMD_CMD 0x7f
  106: 
  107: #define CMD_NOP      0x00
  108: #define CMD_FLUSH    0x01
  109: #define CMD_RESET    0x02
  110: #define CMD_BUSRESET 0x03
  111: #define CMD_TI       0x10
  112: #define CMD_ICCS     0x11
  113: #define CMD_MSGACC   0x12
  114: #define CMD_SATN     0x1a
  115: #define CMD_SELATN   0x42
  116: #define CMD_SELATNS  0x43
  117: #define CMD_ENSEL    0x44
  118: 
  119: #define STAT_DO 0x00
  120: #define STAT_DI 0x01
  121: #define STAT_CD 0x02
  122: #define STAT_ST 0x03
  123: #define STAT_MI 0x06
  124: #define STAT_MO 0x07
  125: #define STAT_PIO_MASK 0x06
  126: 
  127: #define STAT_TC 0x10
  128: #define STAT_PE 0x20
  129: #define STAT_GE 0x40
  130: #define STAT_IN 0x80
  131: 
  132: #define INTR_FC 0x08
  133: #define INTR_BS 0x10
  134: #define INTR_DC 0x20
  135: #define INTR_RST 0x80
  136: 
  137: #define SEQ_0 0x0
  138: #define SEQ_CD 0x4
  139: 
  140: #define CFG1_RESREPT 0x40
  141: 
  142: #define CFG2_MASK 0x15
  143: 
  144: #define TCHI_FAS100A 0x4
  145: 
  146: static int get_cmd(ESPState *s, uint8_t *buf)
  147: {
  148:     uint32_t dmalen;
  149:     int target;
  150: 
  151:     dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
  152:     target = s->wregs[ESP_WBUSID] & 7;
  153:     DPRINTF("get_cmd: len %d target %d\n", dmalen, target);
  154:     if (s->dma) {
  155:         espdma_memory_read(s->dma_opaque, buf, dmalen);
  156:     } else {
  157:         buf[0] = 0;
  158:         memcpy(&buf[1], s->ti_buf, dmalen);
  159:         dmalen++;
  160:     }
  161: 
  162:     s->ti_size = 0;
  163:     s->ti_rptr = 0;
  164:     s->ti_wptr = 0;
  165: 
  166:     if (s->current_dev) {
  167:         /* Started a new command before the old one finished.  Cancel it.  */
  168:         s->current_dev->cancel_io(s->current_dev, 0);
  169:         s->async_len = 0;
  170:     }
  171: 
  172:     if (target >= ESP_MAX_DEVS || !s->scsi_dev[target]) {
  173:         // No such drive
  174:         s->rregs[ESP_RSTAT] = STAT_IN;
  175:         s->rregs[ESP_RINTR] = INTR_DC;
  176:         s->rregs[ESP_RSEQ] = SEQ_0;
  177:         qemu_irq_raise(s->irq);
  178:         return 0;
  179:     }
  180:     s->current_dev = s->scsi_dev[target];
  181:     return dmalen;
  182: }
  183: 
  184: static void do_cmd(ESPState *s, uint8_t *buf)
  185: {
  186:     int32_t datalen;
  187:     int lun;
  188: 
  189:     DPRINTF("do_cmd: busid 0x%x\n", buf[0]);
  190:     lun = buf[0] & 7;
  191:     datalen = s->current_dev->send_command(s->current_dev, 0, &buf[1], lun);
  192:     s->ti_size = datalen;
  193:     if (datalen != 0) {
  194:         s->rregs[ESP_RSTAT] = STAT_IN | STAT_TC;
  195:         s->dma_left = 0;
  196:         s->dma_counter = 0;
  197:         if (datalen > 0) {
  198:             s->rregs[ESP_RSTAT] |= STAT_DI;
  199:             s->current_dev->read_data(s->current_dev, 0);
  200:         } else {
  201:             s->rregs[ESP_RSTAT] |= STAT_DO;
  202:             s->current_dev->write_data(s->current_dev, 0);
  203:         }
  204:     }
  205:     s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
  206:     s->rregs[ESP_RSEQ] = SEQ_CD;
  207:     qemu_irq_raise(s->irq);
  208: }
  209: 
  210: static void handle_satn(ESPState *s)
  211: {
  212:     uint8_t buf[32];
  213:     int len;
  214: 
  215:     len = get_cmd(s, buf);
  216:     if (len)
  217:         do_cmd(s, buf);
  218: }
  219: 
  220: static void handle_satn_stop(ESPState *s)
  221: {
  222:     s->cmdlen = get_cmd(s, s->cmdbuf);
  223:     if (s->cmdlen) {
  224:         DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen);
  225:         s->do_cmd = 1;
  226:         s->rregs[ESP_RSTAT] = STAT_IN | STAT_TC | STAT_CD;
  227:         s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
  228:         s->rregs[ESP_RSEQ] = SEQ_CD;
  229:         qemu_irq_raise(s->irq);
  230:     }
  231: }
  232: 
  233: static void write_response(ESPState *s)
  234: {
  235:     DPRINTF("Transfer status (sense=%d)\n", s->sense);
  236:     s->ti_buf[0] = s->sense;
  237:     s->ti_buf[1] = 0;
  238:     if (s->dma) {
  239:         espdma_memory_write(s->dma_opaque, s->ti_buf, 2);
  240:         s->rregs[ESP_RSTAT] = STAT_IN | STAT_TC | STAT_ST;
  241:         s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
  242:         s->rregs[ESP_RSEQ] = SEQ_CD;
  243:     } else {
  244:         s->ti_size = 2;
  245:         s->ti_rptr = 0;
  246:         s->ti_wptr = 0;
  247:         s->rregs[ESP_RFLAGS] = 2;
  248:     }
  249:     qemu_irq_raise(s->irq);
  250: }
  251: 
  252: static void esp_dma_done(ESPState *s)
  253: {
  254:     s->rregs[ESP_RSTAT] |= STAT_IN | STAT_TC;
  255:     s->rregs[ESP_RINTR] = INTR_BS;
  256:     s->rregs[ESP_RSEQ] = 0;
  257:     s->rregs[ESP_RFLAGS] = 0;
  258:     s->rregs[ESP_TCLO] = 0;
  259:     s->rregs[ESP_TCMID] = 0;
  260:     qemu_irq_raise(s->irq);
  261: }
  262: 
  263: static void esp_do_dma(ESPState *s)
  264: {
  265:     uint32_t len;
  266:     int to_device;
  267: 
  268:     to_device = (s->ti_size < 0);
  269:     len = s->dma_left;
  270:     if (s->do_cmd) {
  271:         DPRINTF("command len %d + %d\n", s->cmdlen, len);
  272:         espdma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
  273:         s->ti_size = 0;
  274:         s->cmdlen = 0;
  275:         s->do_cmd = 0;
  276:         do_cmd(s, s->cmdbuf);
  277:         return;
  278:     }
  279:     if (s->async_len == 0) {
  280:         /* Defer until data is available.  */
  281:         return;
  282:     }
  283:     if (len > s->async_len) {
  284:         len = s->async_len;
  285:     }
  286:     if (to_device) {
  287:         espdma_memory_read(s->dma_opaque, s->async_buf, len);
  288:     } else {
  289:         espdma_memory_write(s->dma_opaque, s->async_buf, len);
  290:     }
  291:     s->dma_left -= len;
  292:     s->async_buf += len;
  293:     s->async_len -= len;
  294:     if (to_device)
  295:         s->ti_size += len;
  296:     else
  297:         s->ti_size -= len;
  298:     if (s->async_len == 0) {
  299:         if (to_device) {
  300:             // ti_size is negative
  301:             s->current_dev->write_data(s->current_dev, 0);
  302:         } else {
  303:             s->current_dev->read_data(s->current_dev, 0);
  304:             /* If there is still data to be read from the device then
  305:                complete the DMA operation immeriately.  Otherwise defer
  306:                until the scsi layer has completed.  */
  307:             if (s->dma_left == 0 && s->ti_size > 0) {
  308:                 esp_dma_done(s);
  309:             }
  310:         }
  311:     } else {
  312:         /* Partially filled a scsi buffer. Complete immediately.  */
  313:         esp_dma_done(s);
  314:     }
  315: }
  316: 
  317: static void esp_command_complete(void *opaque, int reason, uint32_t tag,
  318:                                  uint32_t arg)
  319: {
  320:     ESPState *s = (ESPState *)opaque;
  321: 
  322:     if (reason == SCSI_REASON_DONE) {
  323:         DPRINTF("SCSI Command complete\n");
  324:         if (s->ti_size != 0)
  325:             DPRINTF("SCSI command completed unexpectedly\n");
  326:         s->ti_size = 0;
  327:         s->dma_left = 0;
  328:         s->async_len = 0;
  329:         if (arg)
  330:             DPRINTF("Command failed\n");
  331:         s->sense = arg;
  332:         s->rregs[ESP_RSTAT] = STAT_ST;
  333:         esp_dma_done(s);
  334:         s->current_dev = NULL;
  335:     } else {
  336:         DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size);
  337:         s->async_len = arg;
  338:         s->async_buf = s->current_dev->get_buf(s->current_dev, 0);
  339:         if (s->dma_left) {
  340:             esp_do_dma(s);
  341:         } else if (s->dma_counter != 0 && s->ti_size <= 0) {
  342:             /* If this was the last part of a DMA transfer then the
  343:                completion interrupt is deferred to here.  */
  344:             esp_dma_done(s);
  345:         }
  346:     }
  347: }
  348: 
  349: static void handle_ti(ESPState *s)
  350: {
  351:     uint32_t dmalen, minlen;
  352: 
  353:     dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
  354:     if (dmalen==0) {
  355:       dmalen=0x10000;
  356:     }
  357:     s->dma_counter = dmalen;
  358: 
  359:     if (s->do_cmd)
  360:         minlen = (dmalen < 32) ? dmalen : 32;
  361:     else if (s->ti_size < 0)
  362:         minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
  363:     else
  364:         minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
  365:     DPRINTF("Transfer Information len %d\n", minlen);
  366:     if (s->dma) {
  367:         s->dma_left = minlen;
  368:         s->rregs[ESP_RSTAT] &= ~STAT_TC;
  369:         esp_do_dma(s);
  370:     } else if (s->do_cmd) {
  371:         DPRINTF("command len %d\n", s->cmdlen);
  372:         s->ti_size = 0;
  373:         s->cmdlen = 0;
  374:         s->do_cmd = 0;
  375:         do_cmd(s, s->cmdbuf);
  376:         return;
  377:     }
  378: }
  379: 
  380: static void esp_reset(void *opaque)
  381: {
  382:     ESPState *s = opaque;
  383: 
  384:     memset(s->rregs, 0, ESP_REGS);
  385:     memset(s->wregs, 0, ESP_REGS);
  386:     s->rregs[ESP_TCHI] = TCHI_FAS100A; // Indicate fas100a
  387:     s->ti_size = 0;
  388:     s->ti_rptr = 0;
  389:     s->ti_wptr = 0;
  390:     s->dma = 0;
  391:     s->do_cmd = 0;
  392: }
  393: 
  394: static void parent_esp_reset(void *opaque, int irq, int level)
  395: {
  396:     if (level)
  397:         esp_reset(opaque);
  398: }
  399: 
  400: static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
  401: {
  402:     ESPState *s = opaque;
  403:     uint32_t saddr;
  404: 
  405:     saddr = (addr & ESP_MASK) >> 2;
  406:     DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]);
  407:     switch (saddr) {
  408:     case ESP_FIFO:
  409:         if (s->ti_size > 0) {
  410:             s->ti_size--;
  411:             if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
  412:                 /* Data in/out.  */
  413:                 fprintf(stderr, "esp: PIO data read not implemented\n");
  414:                 s->rregs[ESP_FIFO] = 0;
  415:             } else {
  416:                 s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
  417:             }
  418:             qemu_irq_raise(s->irq);
  419:         }
  420:         if (s->ti_size == 0) {
  421:             s->ti_rptr = 0;
  422:             s->ti_wptr = 0;
  423:         }
  424:         break;
  425:     case ESP_RINTR:
  426:         // Clear interrupt/error status bits
  427:         s->rregs[ESP_RSTAT] &= ~(STAT_IN | STAT_GE | STAT_PE);
  428:         qemu_irq_lower(s->irq);
  429:         break;
  430:     default:
  431:         break;
  432:     }
  433:     return s->rregs[saddr];
  434: }
  435: 
  436: static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
  437: {
  438:     ESPState *s = opaque;
  439:     uint32_t saddr;
  440: 
  441:     saddr = (addr & ESP_MASK) >> 2;
  442:     DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr],
  443:             val);
  444:     switch (saddr) {
  445:     case ESP_TCLO:
  446:     case ESP_TCMID:
  447:         s->rregs[ESP_RSTAT] &= ~STAT_TC;
  448:         break;
  449:     case ESP_FIFO:
  450:         if (s->do_cmd) {
  451:             s->cmdbuf[s->cmdlen++] = val & 0xff;
  452:         } else if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
  453:             uint8_t buf;
  454:             buf = val & 0xff;
  455:             s->ti_size--;
  456:             fprintf(stderr, "esp: PIO data write not implemented\n");
  457:         } else {
  458:             s->ti_size++;
  459:             s->ti_buf[s->ti_wptr++] = val & 0xff;
  460:         }
  461:         break;
  462:     case ESP_CMD:
  463:         s->rregs[saddr] = val;
  464:         if (val & CMD_DMA) {
  465:             s->dma = 1;
  466:             /* Reload DMA counter.  */
  467:             s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
  468:             s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
  469:         } else {
  470:             s->dma = 0;
  471:         }
  472:         switch(val & CMD_CMD) {
  473:         case CMD_NOP:
  474:             DPRINTF("NOP (%2.2x)\n", val);
  475:             break;
  476:         case CMD_FLUSH:
  477:             DPRINTF("Flush FIFO (%2.2x)\n", val);
  478:             //s->ti_size = 0;
  479:             s->rregs[ESP_RINTR] = INTR_FC;
  480:             s->rregs[ESP_RSEQ] = 0;
  481:             break;
  482:         case CMD_RESET:
  483:             DPRINTF("Chip reset (%2.2x)\n", val);
  484:             esp_reset(s);
  485:             break;
  486:         case CMD_BUSRESET:
  487:             DPRINTF("Bus reset (%2.2x)\n", val);
  488:             s->rregs[ESP_RINTR] = INTR_RST;
  489:             if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
  490:                 qemu_irq_raise(s->irq);
  491:             }
  492:             break;
  493:         case CMD_TI:
  494:             handle_ti(s);
  495:             break;
  496:         case CMD_ICCS:
  497:             DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);
  498:             write_response(s);
  499:             break;
  500:         case CMD_MSGACC:
  501:             DPRINTF("Message Accepted (%2.2x)\n", val);
  502:             write_response(s);
  503:             s->rregs[ESP_RINTR] = INTR_DC;
  504:             s->rregs[ESP_RSEQ] = 0;
  505:             break;
  506:         case CMD_SATN:
  507:             DPRINTF("Set ATN (%2.2x)\n", val);
  508:             break;
  509:         case CMD_SELATN:
  510:             DPRINTF("Set ATN (%2.2x)\n", val);
  511:             handle_satn(s);
  512:             break;
  513:         case CMD_SELATNS:
  514:             DPRINTF("Set ATN & stop (%2.2x)\n", val);
  515:             handle_satn_stop(s);
  516:             break;
  517:         case CMD_ENSEL:
  518:             DPRINTF("Enable selection (%2.2x)\n", val);
  519:             break;
  520:         default:
  521:             DPRINTF("Unhandled ESP command (%2.2x)\n", val);
  522:             break;
  523:         }
  524:         break;
  525:     case ESP_WBUSID ... ESP_WSYNO:
  526:         break;
  527:     case ESP_CFG1:
  528:         s->rregs[saddr] = val;
  529:         break;
  530:     case ESP_WCCF ... ESP_WTEST:
  531:         break;
  532:     case ESP_CFG2:
  533:         s->rregs[saddr] = val & CFG2_MASK;
  534:         break;
  535:     case ESP_CFG3 ... ESP_RES4:
  536:         s->rregs[saddr] = val;
  537:         break;
  538:     default:
  539:         break;
  540:     }
  541:     s->wregs[saddr] = val;
  542: }
  543: 
  544: static CPUReadMemoryFunc *esp_mem_read[3] = {
  545:     esp_mem_readb,
  546:     NULL,
  547:     NULL,
  548: };
  549: 
  550: static CPUWriteMemoryFunc *esp_mem_write[3] = {
  551:     esp_mem_writeb,
  552:     NULL,
  553:     NULL,
  554: };
  555: 
  556: static void esp_save(QEMUFile *f, void *opaque)
  557: {
  558:     ESPState *s = opaque;
  559: 
  560:     qemu_put_buffer(f, s->rregs, ESP_REGS);
  561:     qemu_put_buffer(f, s->wregs, ESP_REGS);
  562:     qemu_put_be32s(f, &s->ti_size);
  563:     qemu_put_be32s(f, &s->ti_rptr);
  564:     qemu_put_be32s(f, &s->ti_wptr);
  565:     qemu_put_buffer(f, s->ti_buf, TI_BUFSZ);
  566:     qemu_put_be32s(f, &s->sense);
  567:     qemu_put_be32s(f, &s->dma);
  568:     qemu_put_buffer(f, s->cmdbuf, TI_BUFSZ);