Commit 7d8406be69ce936839300159fcf2a0c4863f7f08

Authored by pbrook
1 parent 0fc5c15a

PCI SCSI HBA emulation.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1946 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -307,7 +307,7 @@ SOUND_HW += fmopl.o adlib.o
307 307 endif
308 308  
309 309 # SCSI layer
310   -VL_OBJS+= scsi-disk.o cdrom.o
  310 +VL_OBJS+= scsi-disk.o cdrom.o lsi53c895a.o
311 311  
312 312 # USB layer
313 313 VL_OBJS+= usb.o usb-hub.o usb-linux.o usb-hid.o usb-ohci.o usb-msd.o
... ...
hw/lsi53c895a.c 0 → 100644
  1 +/*
  2 + * QEMU LSI53C895A SCSI Host Bus Adapter emulation
  3 + *
  4 + * Copyright (c) 2006 CodeSourcery.
  5 + * Written by Paul Brook
  6 + *
  7 + * This code is licenced under the LGPL.
  8 + */
  9 +
  10 +/* ??? Need to check if the {read,write}[wl] routines work properly on
  11 + big-endian targets. */
  12 +
  13 +#include "vl.h"
  14 +
  15 +//#define DEBUG_LSI
  16 +//#define DEBUG_LSI_REG
  17 +
  18 +#ifdef DEBUG_LSI
  19 +#define DPRINTF(fmt, args...) \
  20 +do { printf("lsi_scsi: " fmt , ##args); } while (0)
  21 +#define BADF(fmt, args...) \
  22 +do { fprintf(stderr, "lsi_scsi: " fmt , ##args); exit(1);} while (0)
  23 +#else
  24 +#define DPRINTF(fmt, args...) do {} while(0)
  25 +#define BADF(fmt, args...) \
  26 +do { fprintf(stderr, "lsi_scsi: " fmt , ##args); } while (0)
  27 +#endif
  28 +
  29 +#define LSI_SCNTL0_TRG 0x01
  30 +#define LSI_SCNTL0_AAP 0x02
  31 +#define LSI_SCNTL0_EPC 0x08
  32 +#define LSI_SCNTL0_WATN 0x10
  33 +#define LSI_SCNTL0_START 0x20
  34 +
  35 +#define LSI_SCNTL1_SST 0x01
  36 +#define LSI_SCNTL1_IARB 0x02
  37 +#define LSI_SCNTL1_AESP 0x04
  38 +#define LSI_SCNTL1_RST 0x08
  39 +#define LSI_SCNTL1_CON 0x10
  40 +#define LSI_SCNTL1_DHP 0x20
  41 +#define LSI_SCNTL1_ADB 0x40
  42 +#define LSI_SCNTL1_EXC 0x80
  43 +
  44 +#define LSI_SCNTL2_WSR 0x01
  45 +#define LSI_SCNTL2_VUE0 0x02
  46 +#define LSI_SCNTL2_VUE1 0x04
  47 +#define LSI_SCNTL2_WSS 0x08
  48 +#define LSI_SCNTL2_SLPHBEN 0x10
  49 +#define LSI_SCNTL2_SLPMD 0x20
  50 +#define LSI_SCNTL2_CHM 0x40
  51 +#define LSI_SCNTL2_SDU 0x80
  52 +
  53 +#define LSI_ISTAT0_DIP 0x01
  54 +#define LSI_ISTAT0_SIP 0x02
  55 +#define LSI_ISTAT0_INTF 0x04
  56 +#define LSI_ISTAT0_CON 0x08
  57 +#define LSI_ISTAT0_SEM 0x10
  58 +#define LSI_ISTAT0_SIGP 0x20
  59 +#define LSI_ISTAT0_SRST 0x40
  60 +#define LSI_ISTAT0_ABRT 0x80
  61 +
  62 +#define LSI_ISTAT1_SI 0x01
  63 +#define LSI_ISTAT1_SRUN 0x02
  64 +#define LSI_ISTAT1_FLSH 0x04
  65 +
  66 +#define LSI_SSTAT0_SDP0 0x01
  67 +#define LSI_SSTAT0_RST 0x02
  68 +#define LSI_SSTAT0_WOA 0x04
  69 +#define LSI_SSTAT0_LOA 0x08
  70 +#define LSI_SSTAT0_AIP 0x10
  71 +#define LSI_SSTAT0_OLF 0x20
  72 +#define LSI_SSTAT0_ORF 0x40
  73 +#define LSI_SSTAT0_ILF 0x80
  74 +
  75 +#define LSI_SIST0_PAR 0x01
  76 +#define LSI_SIST0_RST 0x02
  77 +#define LSI_SIST0_UDC 0x04
  78 +#define LSI_SIST0_SGE 0x08
  79 +#define LSI_SIST0_RSL 0x10
  80 +#define LSI_SIST0_SEL 0x20
  81 +#define LSI_SIST0_CMP 0x40
  82 +#define LSI_SIST0_MA 0x80
  83 +
  84 +#define LSI_SIST1_HTH 0x01
  85 +#define LSI_SIST1_GEN 0x02
  86 +#define LSI_SIST1_STO 0x04
  87 +#define LSI_SIST1_SBMC 0x10
  88 +
  89 +#define LSI_SOCL_IO 0x01
  90 +#define LSI_SOCL_CD 0x02
  91 +#define LSI_SOCL_MSG 0x04
  92 +#define LSI_SOCL_ATN 0x08
  93 +#define LSI_SOCL_SEL 0x10
  94 +#define LSI_SOCL_BSY 0x20
  95 +#define LSI_SOCL_ACK 0x40
  96 +#define LSI_SOCL_REQ 0x80
  97 +
  98 +#define LSI_DSTAT_IID 0x01
  99 +#define LSI_DSTAT_SIR 0x04
  100 +#define LSI_DSTAT_SSI 0x08
  101 +#define LSI_DSTAT_ABRT 0x10
  102 +#define LSI_DSTAT_BF 0x20
  103 +#define LSI_DSTAT_MDPE 0x40
  104 +#define LSI_DSTAT_DFE 0x80
  105 +
  106 +#define LSI_DCNTL_COM 0x01
  107 +#define LSI_DCNTL_IRQD 0x02
  108 +#define LSI_DCNTL_STD 0x04
  109 +#define LSI_DCNTL_IRQM 0x08
  110 +#define LSI_DCNTL_SSM 0x10
  111 +#define LSI_DCNTL_PFEN 0x20
  112 +#define LSI_DCNTL_PFF 0x40
  113 +#define LSI_DCNTL_CLSE 0x80
  114 +
  115 +#define LSI_DMODE_MAN 0x01
  116 +#define LSI_DMODE_BOF 0x02
  117 +#define LSI_DMODE_ERMP 0x04
  118 +#define LSI_DMODE_ERL 0x08
  119 +#define LSI_DMODE_DIOM 0x10
  120 +#define LSI_DMODE_SIOM 0x20
  121 +
  122 +#define LSI_CTEST2_DACK 0x01
  123 +#define LSI_CTEST2_DREQ 0x02
  124 +#define LSI_CTEST2_TEOP 0x04
  125 +#define LSI_CTEST2_PCICIE 0x08
  126 +#define LSI_CTEST2_CM 0x10
  127 +#define LSI_CTEST2_CIO 0x20
  128 +#define LSI_CTEST2_SIGP 0x40
  129 +#define LSI_CTEST2_DDIR 0x80
  130 +
  131 +#define LSI_CTEST5_BL2 0x04
  132 +#define LSI_CTEST5_DDIR 0x08
  133 +#define LSI_CTEST5_MASR 0x10
  134 +#define LSI_CTEST5_DFSN 0x20
  135 +#define LSI_CTEST5_BBCK 0x40
  136 +#define LSI_CTEST5_ADCK 0x80
  137 +
  138 +#define LSI_CCNTL0_DILS 0x01
  139 +#define LSI_CCNTL0_DISFC 0x10
  140 +#define LSI_CCNTL0_ENNDJ 0x20
  141 +#define LSI_CCNTL0_PMJCTL 0x40
  142 +#define LSI_CCNTL0_ENPMJ 0x80
  143 +
  144 +#define PHASE_DO 0
  145 +#define PHASE_DI 1
  146 +#define PHASE_CMD 2
  147 +#define PHASE_ST 3
  148 +#define PHASE_MO 6
  149 +#define PHASE_MI 7
  150 +#define PHASE_MASK 7
  151 +
  152 +/* The HBA is ID 7, so for simplicitly limit to 7 devices. */
  153 +#define LSI_MAX_DEVS 7
  154 +
  155 +typedef struct {
  156 + PCIDevice pci_dev;
  157 + int mmio_io_addr;
  158 + int ram_io_addr;
  159 + uint32_t script_ram_base;
  160 + uint32_t data_len;
  161 +
  162 + int carry; /* ??? Should this be an a visible register somewhere? */
  163 + int sense;
  164 + uint8_t msg;
  165 + /* Nonzero if a Wait Reselect instruction has been issued. */
  166 + int waiting;
  167 + SCSIDevice *scsi_dev[LSI_MAX_DEVS];
  168 + SCSIDevice *current_dev;
  169 + int current_lun;
  170 +
  171 + uint32_t dsa;
  172 + uint32_t temp;
  173 + uint32_t dnad;
  174 + uint32_t dbc;
  175 + uint8_t istat0;
  176 + uint8_t istat1;
  177 + uint8_t dcmd;
  178 + uint8_t dstat;
  179 + uint8_t dien;
  180 + uint8_t sist0;
  181 + uint8_t sist1;
  182 + uint8_t sien0;
  183 + uint8_t sien1;
  184 + uint8_t mbox0;
  185 + uint8_t mbox1;
  186 + uint8_t dfifo;
  187 + uint8_t ctest3;
  188 + uint8_t ctest4;
  189 + uint8_t ctest5;
  190 + uint8_t ccntl0;
  191 + uint8_t ccntl1;
  192 + uint32_t dsp;
  193 + uint32_t dsps;
  194 + uint8_t dmode;
  195 + uint8_t dcntl;
  196 + uint8_t scntl0;
  197 + uint8_t scntl1;
  198 + uint8_t scntl2;
  199 + uint8_t scntl3;
  200 + uint8_t sstat0;
  201 + uint8_t sstat1;
  202 + uint8_t scid;
  203 + uint8_t sxfer;
  204 + uint8_t socl;
  205 + uint8_t sdid;
  206 + uint8_t sfbr;
  207 + uint8_t stest1;
  208 + uint8_t stest2;
  209 + uint8_t stest3;
  210 + uint8_t stime0;
  211 + uint8_t respid0;
  212 + uint8_t respid1;
  213 + uint32_t mmrs;
  214 + uint32_t mmws;
  215 + uint32_t sfs;
  216 + uint32_t drs;
  217 + uint32_t sbms;
  218 + uint32_t dmbs;
  219 + uint32_t dnad64;
  220 + uint32_t pmjad1;
  221 + uint32_t pmjad2;
  222 + uint32_t rbc;
  223 + uint32_t ua;
  224 + uint32_t ia;
  225 + uint32_t sbc;
  226 + uint32_t csbc;
  227 + uint32_t scratch[13]; /* SCRATCHA-SCRATCHR */
  228 +
  229 + /* Script ram is stored as 32-bit words in host byteorder. */
  230 + uint32_t script_ram[2048];
  231 +} LSIState;
  232 +
  233 +static void lsi_soft_reset(LSIState *s)
  234 +{
  235 + DPRINTF("Reset\n");
  236 + s->carry = 0;
  237 +
  238 + s->waiting = 0;
  239 + s->dsa = 0;
  240 + s->dnad = 0;
  241 + s->dbc = 0;
  242 + s->temp = 0;
  243 + memset(s->scratch, 0, sizeof(s->scratch));
  244 + s->istat0 = 0;
  245 + s->istat1 = 0;
  246 + s->dcmd = 0;
  247 + s->dstat = 0;
  248 + s->dien = 0;
  249 + s->sist0 = 0;
  250 + s->sist1 = 0;
  251 + s->sien0 = 0;
  252 + s->sien1 = 0;
  253 + s->mbox0 = 0;
  254 + s->mbox1 = 0;
  255 + s->dfifo = 0;
  256 + s->ctest3 = 0;
  257 + s->ctest4 = 0;
  258 + s->ctest5 = 0;
  259 + s->ccntl0 = 0;
  260 + s->ccntl1 = 0;
  261 + s->dsp = 0;
  262 + s->dsps = 0;
  263 + s->dmode = 0;
  264 + s->dcntl = 0;
  265 + s->scntl0 = 0xc0;
  266 + s->scntl1 = 0;
  267 + s->scntl2 = 0;
  268 + s->scntl3 = 0;
  269 + s->sstat0 = 0;
  270 + s->sstat1 = 0;
  271 + s->scid = 7;
  272 + s->sxfer = 0;
  273 + s->socl = 0;
  274 + s->stest1 = 0;
  275 + s->stest2 = 0;
  276 + s->stest3 = 0;
  277 + s->stime0 = 0;
  278 + s->respid0 = 0x80;
  279 + s->respid1 = 0;
  280 + s->mmrs = 0;
  281 + s->mmws = 0;
  282 + s->sfs = 0;
  283 + s->drs = 0;
  284 + s->sbms = 0;
  285 + s->dmbs = 0;
  286 + s->dnad64 = 0;
  287 + s->pmjad1 = 0;
  288 + s->pmjad2 = 0;
  289 + s->rbc = 0;
  290 + s->ua = 0;
  291 + s->ia = 0;
  292 + s->sbc = 0;
  293 + s->csbc = 0;
  294 +}
  295 +
  296 +static uint8_t lsi_reg_readb(LSIState *s, int offset);
  297 +static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val);
  298 +
  299 +static inline uint32_t read_dword(LSIState *s, uint32_t addr)
  300 +{
  301 + uint32_t buf;
  302 +
  303 + /* Optimize reading from SCRIPTS RAM. */
  304 + if ((addr & 0xffffe000) == s->script_ram_base) {
  305 + return s->script_ram[(addr & 0x1fff) >> 2];
  306 + }
  307 + cpu_physical_memory_read(addr, (uint8_t *)&buf, 4);
  308 + return cpu_to_le32(buf);
  309 +}
  310 +
  311 +static void lsi_stop_script(LSIState *s)
  312 +{
  313 + s->istat1 &= ~LSI_ISTAT1_SRUN;
  314 +}
  315 +
  316 +static void lsi_update_irq(LSIState *s)
  317 +{
  318 + int level;
  319 + static int last_level;
  320 +
  321 + /* It's unclear whether the DIP/SIP bits should be cleared when the
  322 + Interrupt Status Registers are cleared or when istat0 is read.
  323 + We currently do the formwer, which seems to work. */
  324 + level = 0;
  325 + if (s->dstat) {
  326 + if (s->dstat & s->dien)
  327 + level = 1;
  328 + s->istat0 |= LSI_ISTAT0_DIP;
  329 + } else {
  330 + s->istat0 &= ~LSI_ISTAT0_DIP;
  331 + }
  332 +
  333 + if (s->sist0 || s->sist1) {
  334 + if ((s->sist0 & s->sien0) || (s->sist1 & s->sien1))
  335 + level = 1;
  336 + s->istat0 |= LSI_ISTAT0_SIP;
  337 + } else {
  338 + s->istat0 &= ~LSI_ISTAT0_SIP;
  339 + }
  340 + if (s->istat0 & LSI_ISTAT0_INTF)
  341 + level = 1;
  342 +
  343 + if (level != last_level) {
  344 + DPRINTF("Update IRQ level %d dstat %02x sist %02x%02x\n",
  345 + level, s->dstat, s->sist1, s->sist0);
  346 + last_level = level;
  347 + }
  348 + pci_set_irq(&s->pci_dev, 0, level);
  349 +}
  350 +
  351 +/* Stop SCRIPTS execution and raise a SCSI interrupt. */
  352 +static void lsi_script_scsi_interrupt(LSIState *s, int stat0, int stat1)
  353 +{
  354 + uint32_t mask0;
  355 + uint32_t mask1;
  356 +
  357 + DPRINTF("SCSI Interrupt 0x%02x%02x prev 0x%02x%02x\n",
  358 + stat1, stat0, s->sist1, s->sist0);
  359 + s->sist0 |= stat0;
  360 + s->sist1 |= stat1;
  361 + /* Stop processor on fatal or unmasked interrupt. As a special hack
  362 + we don't stop processing when raising STO. Instead continue
  363 + execution and stop at the next insn that accesses the SCSI bus. */
  364 + mask0 = s->sien0 | ~(LSI_SIST0_CMP | LSI_SIST0_SEL | LSI_SIST0_RSL);
  365 + mask1 = s->sien1 | ~(LSI_SIST1_GEN | LSI_SIST1_HTH);
  366 + mask1 &= ~LSI_SIST1_STO;
  367 + if (s->sist0 & mask0 || s->sist1 & mask1) {
  368 + lsi_stop_script(s);
  369 + }
  370 + lsi_update_irq(s);
  371 +}
  372 +
  373 +/* Stop SCRIPTS execution and raise a DMA interrupt. */
  374 +static void lsi_script_dma_interrupt(LSIState *s, int stat)
  375 +{
  376 + DPRINTF("DMA Interrupt 0x%x prev 0x%x\n", stat, s->dstat);
  377 + s->dstat |= stat;
  378 + lsi_update_irq(s);
  379 + lsi_stop_script(s);
  380 +}
  381 +
  382 +static inline void lsi_set_phase(LSIState *s, int phase)
  383 +{
  384 + s->sstat1 = (s->sstat1 & ~PHASE_MASK) | phase;
  385 +}
  386 +
  387 +static void lsi_bad_phase(LSIState *s, int out, int new_phase)
  388 +{
  389 + /* Trigger a phase mismatch. */
  390 + if (s->ccntl0 & LSI_CCNTL0_ENPMJ) {
  391 + if ((s->ccntl0 & LSI_CCNTL0_PMJCTL) || out) {
  392 + s->dsp = s->pmjad1;
  393 + } else {
  394 + s->dsp = s->pmjad2;
  395 + }
  396 + DPRINTF("Data phase mismatch jump to %08x\n", s->dsp);
  397 + } else {
  398 + DPRINTF("Phase mismatch interrupt\n");
  399 + lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
  400 + lsi_stop_script(s);
  401 + }
  402 + lsi_set_phase(s, new_phase);
  403 +}
  404 +
  405 +static void lsi_do_dma(LSIState *s, int out)
  406 +{
  407 + uint8_t buf[TARGET_PAGE_SIZE];
  408 + uint32_t addr;
  409 + uint32_t count;
  410 + int n;
  411 +
  412 + count = s->dbc;
  413 + addr = s->dnad;
  414 + DPRINTF("DMA %s addr=0x%08x len=%d avail=%d\n", out ? "out" : "in",
  415 + addr, count, s->data_len);
  416 + /* ??? Too long transfers are truncated. Don't know if this is the
  417 + correct behavior. */
  418 + if (count > s->data_len) {
  419 + /* If the DMA length is greater then the device data length then
  420 + a phase mismatch will occur. */
  421 + count = s->data_len;
  422 + s->dbc = count;
  423 + lsi_bad_phase(s, out, PHASE_ST);
  424 + }
  425 +
  426 + s->csbc += count;
  427 +
  428 + /* ??? Set SFBR to first data byte. */
  429 + while (count) {
  430 + n = (count > TARGET_PAGE_SIZE) ? TARGET_PAGE_SIZE : count;
  431 + if (out) {
  432 + cpu_physical_memory_read(addr, buf, n);
  433 + scsi_write_data(s->current_dev, buf, n);
  434 + } else {
  435 + scsi_read_data(s->current_dev, buf, n);
  436 + cpu_physical_memory_write(addr, buf, n);
  437 + }
  438 + addr += n;
  439 + count -= n;
  440 + }
  441 +}
  442 +
  443 +
  444 +static void lsi_do_command(LSIState *s)
  445 +{
  446 + uint8_t buf[16];
  447 + int n;
  448 +
  449 + DPRINTF("Send command len=%d\n", s->dbc);
  450 + if (s->dbc > 16)
  451 + s->dbc = 16;
  452 + cpu_physical_memory_read(s->dnad, buf, s->dbc);
  453 + s->sfbr = buf[0];
  454 + n = scsi_send_command(s->current_dev, 0, buf, s->current_lun);
  455 + if (n > 0) {
  456 + s->data_len = n;
  457 + lsi_set_phase(s, PHASE_DI);
  458 + } else if (n < 0) {
  459 + s->data_len = -n;
  460 + lsi_set_phase(s, PHASE_DO);
  461 + }
  462 +}
  463 +
  464 +static void lsi_command_complete(void *opaque, uint32_t tag, int sense)
  465 +{
  466 + LSIState *s = (LSIState *)opaque;
  467 +
  468 + DPRINTF("Command complete sense=%d\n", sense);
  469 + s->sense = sense;
  470 + lsi_set_phase(s, PHASE_ST);
  471 +}
  472 +
  473 +static void lsi_do_status(LSIState *s)
  474 +{
  475 + DPRINTF("Get status len=%d sense=%d\n", s->dbc, s->sense);
  476 + if (s->dbc != 1)
  477 + BADF("Bad Status move\n");
  478 + s->dbc = 1;
  479 + s->msg = s->sense;
  480 + cpu_physical_memory_write(s->dnad, &s->msg, 1);
  481 + s->sfbr = s->msg;
  482 + lsi_set_phase(s, PHASE_MI);
  483 + s->msg = 0; /* COMMAND COMPLETE */
  484 +}
  485 +
  486 +static void lsi_disconnect(LSIState *s)
  487 +{
  488 + s->scntl1 &= ~LSI_SCNTL1_CON;
  489 + s->sstat1 &= ~PHASE_MASK;
  490 +}
  491 +
  492 +static void lsi_do_msgin(LSIState *s)
  493 +{
  494 + DPRINTF("Message in len=%d\n", s->dbc);
  495 + s->dbc = 1;
  496 + s->sfbr = s->msg;
  497 + cpu_physical_memory_write(s->dnad, &s->msg, 1);
  498 + if (s->msg == 0) {
  499 + lsi_disconnect(s);
  500 + } else {
  501 + /* ??? Check if ATN (not yet implemented) is asserted and maybe
  502 + switch to PHASE_MO. */
  503 + lsi_set_phase(s, PHASE_CMD);
  504 + }
  505 +}
  506 +
  507 +static void lsi_do_msgout(LSIState *s)
  508 +{
  509 + uint8_t msg;
  510 +
  511 + DPRINTF("MSG out len=%d\n", s->dbc);
  512 + if (s->dbc != 1) {
  513 + /* Multibyte messages not implemented. */
  514 + s->msg = 7; /* MESSAGE REJECT */
  515 + //s->dbc = 1;
  516 + //lsi_bad_phase(s, 1, PHASE_MI);
  517 + lsi_set_phase(s, PHASE_MI);
  518 + return;
  519 + }
  520 + cpu_physical_memory_read(s->dnad, &msg, 1);
  521 + s->sfbr = msg;
  522 + s->dnad++;
  523 +
  524 + switch (msg) {
  525 + case 0x00:
  526 + DPRINTF("Got Disconnect\n");
  527 + lsi_disconnect(s);
  528 + return;
  529 + case 0x08:
  530 + DPRINTF("Got No Operation\n");
  531 + lsi_set_phase(s, PHASE_CMD);
  532 + return;
  533 + }
  534 + if ((msg & 0x80) == 0) {
  535 + DPRINTF("Unimplemented message 0x%d\n", msg);
  536 + s->msg = 7; /* MESSAGE REJECT */
  537 + lsi_bad_phase(s, 1, PHASE_MI);
  538 + return;
  539 + }
  540 + s->current_lun = msg & 7;
  541 + DPRINTF("Select LUN %d\n", s->current_lun);
  542 + lsi_set_phase(s, PHASE_CMD);
  543 +}
  544 +
  545 +/* Sign extend a 24-bit value. */
  546 +static inline int32_t sxt24(int32_t n)
  547 +{
  548 + return (n << 8) >> 8;
  549 +}
  550 +
  551 +static void lsi_memcpy(LSIState *s, uint32_t dest, uint32_t src, int count)
  552 +{
  553 + int n;
  554 + uint8_t buf[TARGET_PAGE_SIZE];
  555 +
  556 + DPRINTF("memcpy dest 0x%08x src 0x%08x count %d\n", dest, src, count);
  557 + while (count) {
  558 + n = (count > TARGET_PAGE_SIZE) ? TARGET_PAGE_SIZE : count;
  559 + cpu_physical_memory_read(src, buf, n);
  560 + cpu_physical_memory_write(dest, buf, n);
  561 + src += n;
  562 + dest += n;
  563 + count -= n;
  564 + }
  565 +}
  566 +
  567 +static void lsi_execute_script(LSIState *s)
  568 +{
  569 + uint32_t insn;
  570 + uint32_t addr;
  571 + int opcode;
  572 +
  573 + s->istat1 |= LSI_ISTAT1_SRUN;
  574 +again:
  575 + insn = read_dword(s, s->dsp);
  576 + addr = read_dword(s, s->dsp + 4);
  577 + DPRINTF("SCRIPTS dsp=%08x opcode %08x arg %08x\n", s->dsp, insn, addr);
  578 + s->dsps = addr;
  579 + s->dcmd = insn >> 24;
  580 + s->dsp += 8;
  581 + switch (insn >> 30) {
  582 + case 0: /* Block move. */
  583 + if (s->sist1 & LSI_SIST1_STO) {
  584 + DPRINTF("Delayed select timeout\n");
  585 + lsi_stop_script(s);
  586 + break;
  587 + }
  588 + s->dbc = insn & 0xffffff;
  589 + s->rbc = s->dbc;
  590 + if (insn & (1 << 29)) {
  591 + /* Indirect addressing. */
  592 + addr = read_dword(s, addr);
  593 + } else if (insn & (1 << 28)) {
  594 + uint32_t buf[2];
  595 + int32_t offset;
  596 + /* Table indirect addressing. */
  597 + offset = sxt24(addr);
  598 + cpu_physical_memory_read(s->dsa + offset, (uint8_t *)buf, 8);
  599 + s->dbc = cpu_to_le32(buf[0]);
  600 + addr = cpu_to_le32(buf[1]);
  601 + }
  602 + if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) {
  603 + DPRINTF("Wrong phase got %d expected %d\n",
  604 + s->sstat1 & PHASE_MASK, (insn >> 24) & 7);
  605 + lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
  606 + break;
  607 + }
  608 + s->dnad = addr;
  609 + switch (s->sstat1 & 0x7) {
  610 + case PHASE_DO:
  611 + lsi_do_dma(s, 1);
  612 + break;
  613 + case PHASE_DI:
  614 + lsi_do_dma(s, 0);
  615 + break;
  616 + case PHASE_CMD:
  617 + lsi_do_command(s);
  618 + break;
  619 + case PHASE_ST:
  620 + lsi_do_status(s);
  621 + break;
  622 + case PHASE_MO:
  623 + lsi_do_msgout(s);
  624 + break;
  625 + case PHASE_MI:
  626 + lsi_do_msgin(s);
  627 + break;
  628 + default:
  629 + BADF("Unimplemented phase %d\n", s->sstat1 & PHASE_MASK);
  630 + exit(1);
  631 + }
  632 + s->dfifo = s->dbc & 0xff;
  633 + s->ctest5 = (s->ctest5 & 0xfc) | ((s->dbc >> 8) & 3);
  634 + s->sbc = s->dbc;
  635 + s->rbc -= s->dbc;
  636 + s->ua = addr + s->dbc;
  637 + /* ??? Set ESA. */
  638 + s->ia = s->dsp - 8;
  639 + break;
  640 +
  641 + case 1: /* IO or Read/Write instruction. */
  642 + opcode = (insn >> 27) & 7;
  643 + if (opcode < 5) {
  644 + uint32_t id;
  645 +
  646 + if (insn & (1 << 25)) {
  647 + id = read_dword(s, s->dsa + sxt24(insn));
  648 + } else {
  649 + id = addr;
  650 + }
  651 + id = (id >> 16) & 0xf;
  652 + if (insn & (1 << 26)) {
  653 + addr = s->dsp + sxt24(addr);
  654 + }
  655 + s->dnad = addr;
  656 + switch (opcode) {
  657 + case 0: /* Select */
  658 + s->sstat0 |= LSI_SSTAT0_WOA;
  659 + s->scntl1 &= ~LSI_SCNTL1_IARB;
  660 + s->sdid = id;
  661 + if (id >= LSI_MAX_DEVS || !s->scsi_dev[id]) {
  662 + DPRINTF("Selected absent target %d\n", id);
  663 + lsi_script_scsi_interrupt(s, 0, LSI_SIST1_STO);
  664 + lsi_disconnect(s);
  665 + break;
  666 + }
  667 + DPRINTF("Selected target %d%s\n",
  668 + id, insn & (1 << 3) ? " ATN" : "");
  669 + /* ??? Linux drivers compain when this is set. Maybe
  670 + it only applies in low-level mode (unimplemented).
  671 + lsi_script_scsi_interrupt(s, LSI_SIST0_CMP, 0); */
  672 + s->current_dev = s->scsi_dev[id];
  673 + s->scntl1 |= LSI_SCNTL1_CON;
  674 + if (insn & (1 << 3)) {
  675 + s->socl |= LSI_SOCL_ATN;
  676 + }
  677 + lsi_set_phase(s, PHASE_MO);
  678 + break;
  679 + case 1: /* Disconnect */
  680 + DPRINTF("Wait Disconect\n");
  681 + s->scntl1 &= ~LSI_SCNTL1_CON;
  682 + break;
  683 + case 2: /* Wait Reselect */
  684 + DPRINTF("Wait Reselect\n");
  685 + s->waiting = 1;
  686 + break;
  687 + case 3: /* Set */
  688 + DPRINTF("Set%s%s%s%s\n",
  689 + insn & (1 << 3) ? " ATN" : "",
  690 + insn & (1 << 6) ? " ACK" : "",
  691 + insn & (1 << 9) ? " TM" : "",
  692 + insn & (1 << 10) ? " CC" : "");
  693 + if (insn & (1 << 3)) {
  694 + s->socl |= LSI_SOCL_ATN;
  695 + lsi_set_phase(s, PHASE_MO);
  696 + }
  697 + if (insn & (1 << 9)) {
  698 + BADF("Target mode not implemented\n");
  699 + exit(1);
  700 + }
  701 + if (insn & (1 << 10))
  702 + s->carry = 1;
  703 + break;
  704 + case 4: /* Clear */
  705 + DPRINTF("Clear%s%s%s%s\n",
  706 + insn & (1 << 3) ? " ATN" : "",
  707 + insn & (1 << 6) ? " ACK" : "",
  708 + insn & (1 << 9) ? " TM" : "",
  709 + insn & (1 << 10) ? " CC" : "");
  710 + if (insn & (1 << 3)) {
  711 + s->socl &= ~LSI_SOCL_ATN;
  712 + }
  713 + if (insn & (1 << 10))
  714 + s->carry = 0;
  715 + break;
  716 + }
  717 + } else {
  718 + uint8_t op0;
  719 + uint8_t op1;
  720 + uint8_t data8;
  721 + int reg;
  722 + int operator;
  723 +#ifdef DEBUG_LSI
  724 + static const char *opcode_names[3] =
  725 + {"Write", "Read", "Read-Modify-Write"};
  726 + static const char *operator_names[8] =
  727 + {"MOV", "SHL", "OR", "XOR", "AND", "SHR", "ADD", "ADC"};
  728 +#endif
  729 +
  730 + reg = ((insn >> 16) & 0x7f) | (insn & 0x80);
  731 + data8 = (insn >> 8) & 0xff;
  732 + opcode = (insn >> 27) & 7;
  733 + operator = (insn >> 24) & 7;
  734 + DPRINTF("%s reg 0x%x %s data8 %d%s\n",
  735 + opcode_names[opcode - 5], reg,
  736 + operator_names[operator], data8,
  737 + (insn & (1 << 23)) ? " SFBR" : "");
  738 + op0 = op1 = 0;
  739 + switch (opcode) {
  740 + case 5: /* From SFBR */
  741 + op0 = s->sfbr;
  742 + op1 = data8;
  743 + break;
  744 + case 6: /* To SFBR */
  745 + if (operator)
  746 + op0 = lsi_reg_readb(s, reg);
  747 + op1 = data8;
  748 + break;
  749 + case 7: /* Read-modify-write */
  750 + if (operator)
  751 + op0 = lsi_reg_readb(s, reg);
  752 + if (insn & (1 << 23)) {
  753 + op1 = s->sfbr;
  754 + } else {
  755 + op1 = data8;
  756 + }
  757 + break;
  758 + }
  759 +
  760 + switch (operator) {
  761 + case 0: /* move */
  762 + op0 = op1;
  763 + break;
  764 + case 1: /* Shift left */
  765 + op1 = op0 >> 7;
  766 + op0 = (op0 << 1) | s->carry;
  767 + s->carry = op1;
  768 + break;
  769 + case 2: /* OR */
  770 + op0 |= op1;
  771 + break;
  772 + case 3: /* XOR */
  773 + op0 |= op1;
  774 + break;
  775 + case 4: /* AND */
  776 + op0 &= op1;
  777 + break;
  778 + case 5: /* SHR */
  779 + op1 = op0 & 1;
  780 + op0 = (op0 >> 1) | (s->carry << 7);
  781 + break;
  782 + case 6: /* ADD */
  783 + op0 += op1;
  784 + s->carry = op0 < op1;
  785 + break;
  786 + case 7: /* ADC */
  787 + op0 += op1 + s->carry;
  788 + if (s->carry)
  789 + s->carry = op0 <= op1;
  790 + else
  791 + s->carry = op0 < op1;
  792 + break;
  793 + }
  794 +
  795 + switch (opcode) {
  796 + case 5: /* From SFBR */
  797 + case 7: /* Read-modify-write */
  798 + lsi_reg_writeb(s, reg, op0);
  799 + break;
  800 + case 6: /* To SFBR */
  801 + s->sfbr = op0;
  802 + break;
  803 + }
  804 + }
  805 + break;
  806 +
  807 + case 2: /* Transfer Control. */
  808 + {
  809 + int cond;
  810 + int jmp;
  811 +
  812 + if ((insn & 0x002e0000) == 0) {
  813 + DPRINTF("NOP\n");
  814 + break;
  815 + }
  816 + if (s->sist1 & LSI_SIST1_STO) {
  817 + DPRINTF("Delayed select timeout\n");
  818 + lsi_stop_script(s);
  819 + break;
  820 + }
  821 + cond = jmp = (insn & (1 << 19)) != 0;
  822 + if (cond == jmp && (insn & (1 << 21))) {
  823 + DPRINTF("Compare carry %d\n", s->carry == jmp);
  824 + cond = s->carry != 0;
  825 + }
  826 + if (cond == jmp && (insn & (1 << 17))) {
  827 + DPRINTF("Compare phase %d %c= %d\n",
  828 + (s->sstat1 & PHASE_MASK),
  829 + jmp ? '=' : '!',
  830 + ((insn >> 24) & 7));
  831 + cond = (s->sstat1 & PHASE_MASK) == ((insn >> 24) & 7);
  832 + }
  833 + if (cond == jmp && (insn & (1 << 18))) {
  834 + uint8_t mask;
  835 +
  836 + mask = (~insn >> 8) & 0xff;
  837 + DPRINTF("Compare data 0x%x & 0x%x %c= 0x%x\n",
  838 + s->sfbr, mask, jmp ? '=' : '!', insn & mask);
  839 + cond = (s->sfbr & mask) == (insn & mask);
  840 + }
  841 + if (cond == jmp) {
  842 + if (insn & (1 << 23)) {
  843 + /* Relative address. */
  844 + addr = s->dsp + sxt24(addr);
  845 + }
  846 + switch ((insn >> 27) & 7) {
  847 + case 0: /* Jump */
  848 + DPRINTF("Jump to 0x%08x\n", addr);
  849 + s->dsp = addr;
  850 + break;
  851 + case 1: /* Call */
  852 + DPRINTF("Call 0x%08x\n", addr);
  853 + s->temp = s->dsp;
  854 + s->dsp = addr;
  855 + break;
  856 + case 2: /* Return */
  857 + DPRINTF("Return to 0x%08x\n", s->temp);
  858 + s->dsp = s->temp;
  859 + break;
  860 + case 3: /* Interrupt */
  861 + DPRINTF("Interrupt 0x%08x\n", s->dsps);
  862 + if ((insn & (1 << 20)) != 0) {
  863 + s->istat0 |= LSI_ISTAT0_INTF;
  864 + lsi_update_irq(s);
  865 + } else {
  866 + lsi_script_dma_interrupt(s, LSI_DSTAT_SIR);
  867 + }
  868 + break;
  869 + default:
  870 + DPRINTF("Illegal transfer control\n");
  871 + lsi_script_dma_interrupt(s, LSI_DSTAT_IID);
  872 + break;
  873 + }
  874 + } else {
  875 + DPRINTF("Control condition failed\n");
  876 + }
  877 + }
  878 + break;
  879 +
  880 + case 3:
  881 + if ((insn & (1 << 29)) == 0) {
  882 + /* Memory move. */
  883 + uint32_t dest;
  884 + /* ??? The docs imply the destination address is loaded into
  885 + the TEMP register. However the Linux drivers rely on
  886 + the value being presrved. */
  887 + dest = read_dword(s, s->dsp);
  888 + s->dsp += 4;
  889 + lsi_memcpy(s, dest, addr, insn & 0xffffff);
  890 + } else {
  891 + uint8_t data[7];
  892 + int reg;
  893 + int n;
  894 + int i;
  895 +
  896 + if (insn & (1 << 28)) {
  897 + addr = s->dsa + sxt24(addr);
  898 + }
  899 + n = (insn & 7);
  900 + reg = (insn >> 16) & 0xff;
  901 + if (insn & (1 << 24)) {
  902 + DPRINTF("Load reg 0x%x size %d addr 0x%08x\n", reg, n, addr);
  903 + cpu_physical_memory_read(addr, data, n);
  904 + for (i = 0; i < n; i++) {
  905 + lsi_reg_writeb(s, reg + i, data[i]);
  906 + }
  907 + } else {
  908 + DPRINTF("Store reg 0x%x size %d addr 0x%08x\n", reg, n, addr);
  909 + for (i = 0; i < n; i++) {
  910 + data[i] = lsi_reg_readb(s, reg + i);
  911 + }
  912 + cpu_physical_memory_write(addr, data, n);
  913 + }
  914 + }
  915 + }
  916 + /* ??? Need to avoid infinite loops. */
  917 + if (s->istat1 & LSI_ISTAT1_SRUN && !s->waiting) {
  918 + if (s->dcntl & LSI_DCNTL_SSM) {
  919 + lsi_script_dma_interrupt(s, LSI_DSTAT_SSI);
  920 + } else {
  921 + goto again;
  922 + }
  923 + }
  924 + DPRINTF("SCRIPTS execution stopped\n");
  925 +}
  926 +
  927 +static uint8_t lsi_reg_readb(LSIState *s, int offset)
  928 +{
  929 + uint8_t tmp;
  930 +#define CASE_GET_REG32(name, addr) \
  931 + case addr: return s->name & 0xff; \
  932 + case addr + 1: return (s->name >> 8) & 0xff; \
  933 + case addr + 2: return (s->name >> 16) & 0xff; \
  934 + case addr + 3: return (s->name >> 24) & 0xff;
  935 +
  936 +#ifdef DEBUG_LSI_REG
  937 + DPRINTF("Read reg %x\n", offset);
  938 +#endif
  939 + switch (offset) {
  940 + case 0x00: /* SCNTL0 */
  941 + return s->scntl0;
  942 + case 0x01: /* SCNTL1 */
  943 + return s->scntl1;
  944 + case 0x02: /* SCNTL2 */
  945 + return s->scntl2;
  946 + case 0x03: /* SCNTL3 */
  947 + return s->scntl3;
  948 + case 0x04: /* SCID */
  949 + return s->scid;
  950 + case 0x05: /* SXFER */
  951 + return s->sxfer;
  952 + case 0x06: /* SDID */
  953 + return s->sdid;
  954 + case 0x07: /* GPREG0 */
  955 + return 0x7f;
  956 + case 0xb: /* SBCL */
  957 + /* ??? This is not correct. However it's (hopefully) only
  958 + used for diagnostics, so should be ok. */
  959 + return 0;
  960 + case 0xc: /* DSTAT */
  961 + tmp = s->dstat | 0x80;
  962 + if ((s->istat0 & LSI_ISTAT0_INTF) == 0)
  963 + s->dstat = 0;
  964 + lsi_update_irq(s);
  965 + return tmp;
  966 + case 0x0d: /* SSTAT0 */
  967 + return s->sstat0;
  968 + case 0x0e: /* SSTAT1 */
  969 + return s->sstat1;
  970 + case 0x0f: /* SSTAT2 */
  971 + return s->scntl1 & LSI_SCNTL1_CON ? 0 : 2;
  972 + CASE_GET_REG32(dsa, 0x10)
  973 + case 0x14: /* ISTAT0 */
  974 + return s->istat0;
  975 + case 0x16: /* MBOX0 */
  976 + return s->mbox0;
  977 + case 0x17: /* MBOX1 */
  978 + return s->mbox1;
  979 + case 0x18: /* CTEST0 */
  980 + return 0xff;
  981 + case 0x19: /* CTEST1 */
  982 + return 0;
  983 + case 0x1a: /* CTEST2 */
  984 + tmp = LSI_CTEST2_DACK | LSI_CTEST2_CM;
  985 + if (s->istat0 & LSI_ISTAT0_SIGP) {
  986 + s->istat0 &= ~LSI_ISTAT0_SIGP;
  987 + tmp |= LSI_CTEST2_SIGP;
  988 + }
  989 + return tmp;
  990 + case 0x1b: /* CTEST3 */
  991 + return s->ctest3;
  992 + CASE_GET_REG32(temp, 0x1c)
  993 + case 0x20: /* DFIFO */
  994 + return 0;
  995 + case 0x21: /* CTEST4 */
  996 + return s->ctest4;
  997 + case 0x22: /* CTEST5 */
  998 + return s->ctest5;
  999 + case 0x24: /* DBC[0:7] */
  1000 + return s->dbc & 0xff;
  1001 + case 0x25: /* DBC[8:15] */
  1002 + return (s->dbc >> 8) & 0xff;
  1003 + case 0x26: /* DBC[16->23] */
  1004 + return (s->dbc >> 16) & 0xff;
  1005 + case 0x27: /* DCMD */
  1006 + return s->dcmd;
  1007 + CASE_GET_REG32(dsp, 0x2c)
  1008 + CASE_GET_REG32(dsps, 0x30)
  1009 + CASE_GET_REG32(scratch[0], 0x34)
  1010 + case 0x38: /* DMODE */
  1011 + return s->dmode;
  1012 + case 0x39: /* DIEN */
  1013 + return s->dien;
  1014 + case 0x3b: /* DCNTL */
  1015 + return s->dcntl;
  1016 + case 0x40: /* SIEN0 */
  1017 + return s->sien0;
  1018 + case 0x41: /* SIEN1 */
  1019 + return s->sien1;
  1020 + case 0x42: /* SIST0 */
  1021 + tmp = s->sist0;
  1022 + s->sist0 = 0;
  1023 + lsi_update_irq(s);
  1024 + return tmp;
  1025 + case 0x43: /* SIST1 */
  1026 + tmp = s->sist1;
  1027 + s->sist1 = 0;
  1028 + lsi_update_irq(s);
  1029 + return tmp;
  1030 + case 0x47: /* GPCNTL0 */
  1031 + return 0x0f;
  1032 + case 0x48: /* STIME0 */
  1033 + return s->stime0;
  1034 + case 0x4a: /* RESPID0 */
  1035 + return s->respid0;
  1036 + case 0x4b: /* RESPID1 */
  1037 + return s->respid1;
  1038 + case 0x4d: /* STEST1 */
  1039 + return s->stest1;
  1040 + case 0x4e: /* STEST2 */
  1041 + return s->stest2;
  1042 + case 0x4f: /* STEST3 */
  1043 + return s->stest3;
  1044 + case 0x52: /* STEST4 */
  1045 + return 0xe0;
  1046 + case 0x56: /* CCNTL0 */
  1047 + return s->ccntl0;
  1048 + case 0x57: /* CCNTL1 */
  1049 + return s->ccntl1;
  1050 + case 0x58: case 0x59: /* SBDL */
  1051 + return 0;
  1052 + CASE_GET_REG32(mmrs, 0xa0)
  1053 + CASE_GET_REG32(mmws, 0xa4)
  1054 + CASE_GET_REG32(sfs, 0xa8)
  1055 + CASE_GET_REG32(drs, 0xac)
  1056 + CASE_GET_REG32(sbms, 0xb0)
  1057 + CASE_GET_REG32(dmbs, 0xb4)
  1058 + CASE_GET_REG32(dnad64, 0xb8)
  1059 + CASE_GET_REG32(pmjad1, 0xc0)
  1060 + CASE_GET_REG32(pmjad2, 0xc4)
  1061 + CASE_GET_REG32(rbc, 0xc8)
  1062 + CASE_GET_REG32(ua, 0xcc)
  1063 + CASE_GET_REG32(ia, 0xd4)
  1064 + CASE_GET_REG32(sbc, 0xd8)
  1065 + CASE_GET_REG32(csbc, 0xdc)
  1066 + }
  1067 + if (offset >= 0x5c && offset < 0xa0) {
  1068 + int n;
  1069 + int shift;
  1070 + n = (offset - 0x58) >> 2;
  1071 + shift = (offset & 3) * 8;
  1072 + return (s->scratch[n] >> shift) & 0xff;
  1073 + }
  1074 + BADF("readb 0x%x\n", offset);
  1075 + exit(1);
  1076 +#undef CASE_GET_REG32
  1077 +}
  1078 +
  1079 +static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
  1080 +{
  1081 +#define CASE_SET_REG32(name, addr) \
  1082 + case addr : s->name &= 0xffffff00; s->name |= val; break; \
  1083 + case addr + 1: s->name &= 0xffff00ff; s->name |= val << 8; break; \
  1084 + case addr + 2: s->name &= 0xff00ffff; s->name |= val << 16; break; \
  1085 + case addr + 3: s->name &= 0x00ffffff; s->name |= val << 24; break;
  1086 +
  1087 +#ifdef DEBUG_LSI_REG
  1088 + DPRINTF("Write reg %x = %02x\n", offset, val);
  1089 +#endif
  1090 + switch (offset) {
  1091 + case 0x00: /* SCNTL0 */
  1092 + s->scntl0 = val;
  1093 + if (val & LSI_SCNTL0_START) {
  1094 + BADF("Start sequence not implemented\n");
  1095 + }
  1096 + break;
  1097 + case 0x01: /* SCNTL1 */
  1098 + s->scntl1 = val & ~LSI_SCNTL1_SST;
  1099 + if (val & LSI_SCNTL1_IARB) {
  1100 + BADF("Immediate Arbritration not implemented\n");
  1101 + }
  1102 + if (val & LSI_SCNTL1_RST) {
  1103 + s->sstat0 |= LSI_SSTAT0_RST;
  1104 + lsi_script_scsi_interrupt(s, LSI_SIST0_RST, 0);
  1105 + } else {
  1106 + s->sstat0 &= ~LSI_SSTAT0_RST;
  1107 + }
  1108 + break;
  1109 + case 0x02: /* SCNTL2 */
  1110 + val &= ~(LSI_SCNTL2_WSR | LSI_SCNTL2_WSS);
  1111 + s->scntl3 = val;
  1112 + break;
  1113 + case 0x03: /* SCNTL3 */
  1114 + s->scntl3 = val;
  1115 + break;
  1116 + case 0x04: /* SCID */
  1117 + s->scid = val;
  1118 + break;
  1119 + case 0x05: /* SXFER */
  1120 + s->sxfer = val;
  1121 + break;
  1122 + case 0x07: /* GPREG0 */
  1123 + break;
  1124 + case 0x0c: case 0x0d: case 0x0e: case 0x0f:
  1125 + /* Linux writes to these readonly registers on startup. */
  1126 + return;
  1127 + CASE_SET_REG32(dsa, 0x10)
  1128 + case 0x14: /* ISTAT0 */
  1129 + s->istat0 = (s->istat0 & 0x0f) | (val & 0xf0);
  1130 + if (val & LSI_ISTAT0_ABRT) {
  1131 + lsi_script_dma_interrupt(s, LSI_DSTAT_ABRT);
  1132 + }
  1133 + if (val & LSI_ISTAT0_INTF) {
  1134 + s->istat0 &= ~LSI_ISTAT0_INTF;
  1135 + lsi_update_irq(s);
  1136 + }
  1137 + if (s->waiting && val & LSI_ISTAT0_SIGP) {
  1138 + DPRINTF("Woken by SIGP\n");
  1139 + s->waiting = 0;
  1140 + s->dsp = s->dnad;
  1141 + lsi_execute_script(s);
  1142 + }
  1143 + if (val & LSI_ISTAT0_SRST) {
  1144 + lsi_soft_reset(s);
  1145 + }
  1146 + case 0x16: /* MBOX0 */
  1147 + s->mbox0 = val;
  1148 + case 0x17: /* MBOX1 */
  1149 + s->mbox1 = val;
  1150 + case 0x1b: /* CTEST3 */
  1151 + s->ctest3 = val & 0x0f;
  1152 + break;
  1153 + CASE_SET_REG32(temp, 0x1c)
  1154 + case 0x21: /* CTEST4 */
  1155 + if (val & 7) {
  1156 + BADF("Unimplemented CTEST4-FBL 0x%x\n", val);
  1157 + }
  1158 + s->ctest4 = val;
  1159 + break;
  1160 + case 0x22: /* CTEST5 */
  1161 + if (val & (LSI_CTEST5_ADCK | LSI_CTEST5_BBCK)) {
  1162 + BADF("CTEST5 DMA increment not implemented\n");
  1163 + }
  1164 + s->ctest5 = val;
  1165 + break;
  1166 + case 0x2c: /* DSPS[0:7] */
  1167 + s->dsp &= 0xffffff00;
  1168 + s->dsp |= val;
  1169 + break;
  1170 + case 0x2d: /* DSPS[8:15] */
  1171 + s->dsp &= 0xffff00ff;
  1172 + s->dsp |= val << 8;
  1173 + break;
  1174 + case 0x2e: /* DSPS[16:23] */
  1175 + s->dsp &= 0xff00ffff;
  1176 + s->dsp |= val << 16;
  1177 + break;
  1178 + case 0x2f: /* DSPS[14:31] */
  1179 + s->dsp &= 0x00ffffff;
  1180 + s->dsp |= val << 24;
  1181 + if ((s->dmode & LSI_DMODE_MAN) == 0
  1182 + && (s->istat1 & LSI_ISTAT1_SRUN) == 0)
  1183 + lsi_execute_script(s);
  1184 + break;
  1185 + CASE_SET_REG32(dsps, 0x30)
  1186 + CASE_SET_REG32(scratch[0], 0x34)
  1187 + case 0x38: /* DMODE */
  1188 + if (val & (LSI_DMODE_SIOM | LSI_DMODE_DIOM)) {
  1189 + BADF("IO mappings not implemented\n");
  1190 + }
  1191 + s->dmode = val;
  1192 + break;
  1193 + case 0x39: /* DIEN */
  1194 + s->dien = val;
  1195 + lsi_update_irq(s);
  1196 + break;
  1197 + case 0x3b: /* DCNTL */
  1198 + s->dcntl = val & ~(LSI_DCNTL_PFF | LSI_DCNTL_STD);
  1199 + if ((val & LSI_DCNTL_STD) && (s->istat1 & LSI_ISTAT1_SRUN) == 0)
  1200 + lsi_execute_script(s);
  1201 + break;
  1202 + case 0x40: /* SIEN0 */
  1203 + s->sien0 = val;
  1204 + lsi_update_irq(s);
  1205 + break;
  1206 + case 0x41: /* SIEN1 */
  1207 + s->sien1 = val;
  1208 + lsi_update_irq(s);
  1209 + break;
  1210 + case 0x47: /* GPCNTL0 */
  1211 + break;
  1212 + case 0x48: /* STIME0 */
  1213 + s->stime0 = val;
  1214 + break;
  1215 + case 0x49: /* STIME1 */
  1216 + if (val & 0xf) {
  1217 + DPRINTF("General purpose timer not implemented\n");
  1218 + /* ??? Raising the interrupt immediately seems to be sufficient
  1219 + to keep the FreeBSD driver happy. */
  1220 + lsi_script_scsi_interrupt(s, 0, LSI_SIST1_GEN);
  1221 + }
  1222 + break;
  1223 + case 0x4a: /* RESPID0 */
  1224 + s->respid0 = val;
  1225 + break;
  1226 + case 0x4b: /* RESPID1 */
  1227 + s->respid1 = val;
  1228 + break;
  1229 + case 0x4d: /* STEST1 */
  1230 + s->stest1 = val;
  1231 + break;
  1232 + case 0x4e: /* STEST2 */
  1233 + if (val & 1) {
  1234 + BADF("Low level mode not implemented\n");
  1235 + }
  1236 + s->stest2 = val;
  1237 + break;
  1238 + case 0x4f: /* STEST3 */
  1239 + if (val & 0x41) {
  1240 + BADF("SCSI FIFO test mode not implemented\n");
  1241 + }
  1242 + s->stest3 = val;
  1243 + break;
  1244 + case 0x56: /* CCNTL0 */
  1245 + s->ccntl0 = val;
  1246 + break;
  1247 + case 0x57: /* CCNTL1 */
  1248 + s->ccntl1 = val;
  1249 + break;
  1250 + CASE_SET_REG32(mmrs, 0xa0)
  1251 + CASE_SET_REG32(mmws, 0xa4)
  1252 + CASE_SET_REG32(sfs, 0xa8)
  1253 + CASE_SET_REG32(drs, 0xac)
  1254 + CASE_SET_REG32(sbms, 0xb0)
  1255 + CASE_SET_REG32(dmbs, 0xb4)
  1256 + CASE_SET_REG32(dnad64, 0xb8)
  1257 + CASE_SET_REG32(pmjad1, 0xc0)
  1258 + CASE_SET_REG32(pmjad2, 0xc4)
  1259 + CASE_SET_REG32(rbc, 0xc8)
  1260 + CASE_SET_REG32(ua, 0xcc)
  1261 + CASE_SET_REG32(ia, 0xd4)
  1262 + CASE_SET_REG32(sbc, 0xd8)
  1263 + CASE_SET_REG32(csbc, 0xdc)
  1264 + default:
  1265 + if (offset >= 0x5c && offset < 0xa0) {
  1266 + int n;
  1267 + int shift;
  1268 + n = (offset - 0x58) >> 2;
  1269 + shift = (offset & 3) * 8;
  1270 + s->scratch[n] &= ~(0xff << shift);
  1271 + s->scratch[n] |= (val & 0xff) << shift;
  1272 + } else {
  1273 + BADF("Unhandled writeb 0x%x = 0x%x\n", offset, val);
  1274 + }
  1275 + }
  1276 +#undef CASE_SET_REG32
  1277 +}
  1278 +
  1279 +static void lsi_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
  1280 +{
  1281 + LSIState *s = (LSIState *)opaque;
  1282 +
  1283 + lsi_reg_writeb(s, addr & 0xff, val);
  1284 +}
  1285 +
  1286 +static void lsi_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
  1287 +{
  1288 + LSIState *s = (LSIState *)opaque;
  1289 +
  1290 + addr &= 0xff;
  1291 + lsi_reg_writeb(s, addr, val & 0xff);
  1292 + lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
  1293 +}
  1294 +
  1295 +static void lsi_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
  1296 +{
  1297 + LSIState *s = (LSIState *)opaque;
  1298 +
  1299 + addr &= 0xff;
  1300 + lsi_reg_writeb(s, addr, val & 0xff);
  1301 + lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
  1302 + lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff);
  1303 + lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff);
  1304 +}
  1305 +
  1306 +static uint32_t lsi_mmio_readb(void *opaque, target_phys_addr_t addr)
  1307 +{
  1308 + LSIState *s = (LSIState *)opaque;
  1309 +
  1310 + return lsi_reg_readb(s, addr & 0xff);
  1311 +}
  1312 +
  1313 +static uint32_t lsi_mmio_readw(void *opaque, target_phys_addr_t addr)
  1314 +{
  1315 + LSIState *s = (LSIState *)opaque;
  1316 + uint32_t val;
  1317 +
  1318 + addr &= 0xff;
  1319 + val = lsi_reg_readb(s, addr);
  1320 + val |= lsi_reg_readb(s, addr + 1) << 8;
  1321 + return val;
  1322 +}
  1323 +
  1324 +static uint32_t lsi_mmio_readl(void *opaque, target_phys_addr_t addr)
  1325 +{
  1326 + LSIState *s = (LSIState *)opaque;
  1327 + uint32_t val;
  1328 + addr &= 0xff;
  1329 + val = lsi_reg_readb(s, addr);
  1330 + val |= lsi_reg_readb(s, addr + 1) << 8;
  1331 + val |= lsi_reg_readb(s, addr + 2) << 16;
  1332 + val |= lsi_reg_readb(s, addr + 3) << 24;
  1333 + return val;
  1334 +}
  1335 +
  1336 +static CPUReadMemoryFunc *lsi_mmio_readfn[3] = {
  1337 + lsi_mmio_readb,
  1338 + lsi_mmio_readw,
  1339 + lsi_mmio_readl,
  1340 +};
  1341 +
  1342 +static CPUWriteMemoryFunc *lsi_mmio_writefn[3] = {
  1343 + lsi_mmio_writeb,
  1344 + lsi_mmio_writew,
  1345 + lsi_mmio_writel,
  1346 +};
  1347 +
  1348 +static void lsi_ram_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
  1349 +{
  1350 + LSIState *s = (LSIState *)opaque;
  1351 + uint32_t newval;
  1352 + int shift;
  1353 +
  1354 + addr &= 0x1fff;
  1355 + newval = s->script_ram[addr >> 2];
  1356 + shift = (addr & 3) * 8;
  1357 + newval &= ~(0xff << shift);
  1358 + newval |= val << shift;
  1359 + s->script_ram[addr >> 2] = newval;
  1360 +}
  1361 +
  1362 +static void lsi_ram_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
  1363 +{
  1364 + LSIState *s = (LSIState *)opaque;
  1365 + uint32_t newval;
  1366 +
  1367 + addr &= 0x1fff;
  1368 + newval = s->script_ram[addr >> 2];
  1369 + if (addr & 2) {
  1370 + newval = (newval & 0xffff) | (val << 16);
  1371 + } else {
  1372 + newval = (newval & 0xffff0000) | val;
  1373 + }
  1374 + s->script_ram[addr >> 2] = newval;
  1375 +}
  1376 +
  1377 +
  1378 +static void lsi_ram_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
  1379 +{
  1380 + LSIState *s = (LSIState *)opaque;
  1381 +
  1382 + addr &= 0x1fff;
  1383 + s->script_ram[addr >> 2] = val;
  1384 +}
  1385 +
  1386 +static uint32_t lsi_ram_readb(void *opaque, target_phys_addr_t addr)
  1387 +{
  1388 + LSIState *s = (LSIState *)opaque;
  1389 + uint32_t val;
  1390 +
  1391 + addr &= 0x1fff;
  1392 + val = s->script_ram[addr >> 2];
  1393 + val >>= (addr & 3) * 8;
  1394 + return val & 0xff;
  1395 +}
  1396 +
  1397 +static uint32_t lsi_ram_readw(void *opaque, target_phys_addr_t addr)
  1398 +{
  1399 + LSIState *s = (LSIState *)opaque;
  1400 + uint32_t val;
  1401 +
  1402 + addr &= 0x1fff;
  1403 + val = s->script_ram[addr >> 2];
  1404 + if (addr & 2)
  1405 + val >>= 16;
  1406 + return le16_to_cpu(val);
  1407 +}
  1408 +
  1409 +static uint32_t lsi_ram_readl(void *opaque, target_phys_addr_t addr)
  1410 +{
  1411 + LSIState *s = (LSIState *)opaque;
  1412 +
  1413 + addr &= 0x1fff;
  1414 + return le32_to_cpu(s->script_ram[addr >> 2]);
  1415 +}
  1416 +
  1417 +static CPUReadMemoryFunc *lsi_ram_readfn[3] = {
  1418 + lsi_ram_readb,
  1419 + lsi_ram_readw,
  1420 + lsi_ram_readl,
  1421 +};
  1422 +
  1423 +static CPUWriteMemoryFunc *lsi_ram_writefn[3] = {
  1424 + lsi_ram_writeb,
  1425 + lsi_ram_writew,
  1426 + lsi_ram_writel,
  1427 +};
  1428 +
  1429 +static uint32_t lsi_io_readb(void *opaque, uint32_t addr)
  1430 +{
  1431 + LSIState *s = (LSIState *)opaque;
  1432 + return lsi_reg_readb(s, addr & 0xff);
  1433 +}
  1434 +
  1435 +static uint32_t lsi_io_readw(void *opaque, uint32_t addr)
  1436 +{
  1437 + LSIState *s = (LSIState *)opaque;
  1438 + uint32_t val;
  1439 + addr &= 0xff;
  1440 + val = lsi_reg_readb(s, addr);
  1441 + val |= lsi_reg_readb(s, addr + 1) << 8;
  1442 + return val;
  1443 +}
  1444 +
  1445 +static uint32_t lsi_io_readl(void *opaque, uint32_t addr)
  1446 +{
  1447 + LSIState *s = (LSIState *)opaque;
  1448 + uint32_t val;
  1449 + addr &= 0xff;
  1450 + val = lsi_reg_readb(s, addr);
  1451 + val |= lsi_reg_readb(s, addr + 1) << 8;
  1452 + val |= lsi_reg_readb(s, addr + 2) << 16;
  1453 + val |= lsi_reg_readb(s, addr + 3) << 24;
  1454 + return val;
  1455 +}
  1456 +
  1457 +static void lsi_io_writeb(void *opaque, uint32_t addr, uint32_t val)
  1458 +{
  1459 + LSIState *s = (LSIState *)opaque;
  1460 + lsi_reg_writeb(s, addr & 0xff, val);
  1461 +}
  1462 +
  1463 +static void lsi_io_writew(void *opaque, uint32_t addr, uint32_t val)
  1464 +{
  1465 + LSIState *s = (LSIState *)opaque;
  1466 + addr &= 0xff;
  1467 + lsi_reg_writeb(s, addr, val & 0xff);
  1468 + lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
  1469 +}
  1470 +
  1471 +static void lsi_io_writel(void *opaque, uint32_t addr, uint32_t val)
  1472 +{
  1473 + LSIState *s = (LSIState *)opaque;
  1474 + addr &= 0xff;
  1475 + lsi_reg_writeb(s, addr, val & 0xff);
  1476 + lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
  1477 + lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff);
  1478 + lsi_reg_writeb(s, addr + 2, (val >> 24) & 0xff);
  1479 +}
  1480 +
  1481 +static void lsi_io_mapfunc(PCIDevice *pci_dev, int region_num,
  1482 + uint32_t addr, uint32_t size, int type)
  1483 +{
  1484 + LSIState *s = (LSIState *)pci_dev;
  1485 +
  1486 + DPRINTF("Mapping IO at %08x\n", addr);
  1487 +
  1488 + register_ioport_write(addr, 256, 1, lsi_io_writeb, s);
  1489 + register_ioport_read(addr, 256, 1, lsi_io_readb, s);
  1490 + register_ioport_write(addr, 256, 2, lsi_io_writew, s);
  1491 + register_ioport_read(addr, 256, 2, lsi_io_readw, s);
  1492 + register_ioport_write(addr, 256, 4, lsi_io_writel, s);
  1493 + register_ioport_read(addr, 256, 4, lsi_io_readl, s);
  1494 +}
  1495 +
  1496 +static void lsi_ram_mapfunc(PCIDevice *pci_dev, int region_num,
  1497 + uint32_t addr, uint32_t size, int type)
  1498 +{
  1499 + LSIState *s = (LSIState *)pci_dev;
  1500 +
  1501 + DPRINTF("Mapping ram at %08x\n", addr);
  1502 + s->script_ram_base = addr;
  1503 + cpu_register_physical_memory(addr + 0, 0x2000, s->ram_io_addr);
  1504 +}
  1505 +
  1506 +static void lsi_mmio_mapfunc(PCIDevice *pci_dev, int region_num,
  1507 + uint32_t addr, uint32_t size, int type)
  1508 +{
  1509 + LSIState *s = (LSIState *)pci_dev;
  1510 +
  1511 + DPRINTF("Mapping registers at %08x\n", addr);
  1512 + cpu_register_physical_memory(addr + 0, 0x400, s->mmio_io_addr);
  1513 +}
  1514 +
  1515 +void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id)
  1516 +{
  1517 + LSIState *s = (LSIState *)opaque;
  1518 +
  1519 + if (id < 0) {
  1520 + for (id = 0; id < LSI_MAX_DEVS; id++) {
  1521 + if (s->scsi_dev[id] == NULL)
  1522 + break;
  1523 + }
  1524 + }
  1525 + if (id >= LSI_MAX_DEVS) {
  1526 + BADF("Bad Device ID %d\n", id);
  1527 + return;
  1528 + }
  1529 + if (s->scsi_dev[id]) {
  1530 + DPRINTF("Destroying device %d\n", id);
  1531 + scsi_disk_destroy(s->scsi_dev[id]);
  1532 + }
  1533 + DPRINTF("Attaching block device %d\n", id);
  1534 + s->scsi_dev[id] = scsi_disk_init(bd, lsi_command_complete, s);
  1535 +}
  1536 +
  1537 +void *lsi_scsi_init(PCIBus *bus, int devfn)
  1538 +{
  1539 + LSIState *s;
  1540 +
  1541 + s = (LSIState *)pci_register_device(bus, "LSI53C895A SCSI HBA",
  1542 + sizeof(*s), devfn, NULL, NULL);
  1543 + if (s == NULL) {
  1544 + fprintf(stderr, "lsi-scsi: Failed to register PCI device\n");
  1545 + return NULL;
  1546 + }
  1547 +
  1548 + s->pci_dev.config[0x00] = 0x00;
  1549 + s->pci_dev.config[0x01] = 0x10;
  1550 + s->pci_dev.config[0x02] = 0x12;
  1551 + s->pci_dev.config[0x03] = 0x00;
  1552 + s->pci_dev.config[0x0b] = 0x01;
  1553 + s->pci_dev.config[0x3d] = 0x01; /* interrupt pin 1 */
  1554 +
  1555 + s->mmio_io_addr = cpu_register_io_memory(0, lsi_mmio_readfn,
  1556 + lsi_mmio_writefn, s);
  1557 + s->ram_io_addr = cpu_register_io_memory(0, lsi_ram_readfn,
  1558 + lsi_ram_writefn, s);
  1559 +
  1560 + pci_register_io_region((struct PCIDevice *)s, 0, 256,
  1561 + PCI_ADDRESS_SPACE_IO, lsi_io_mapfunc);
  1562 + pci_register_io_region((struct PCIDevice *)s, 1, 0x400,
  1563 + PCI_ADDRESS_SPACE_MEM, lsi_mmio_mapfunc);
  1564 + pci_register_io_region((struct PCIDevice *)s, 2, 0x2000,
  1565 + PCI_ADDRESS_SPACE_MEM, lsi_ram_mapfunc);
  1566 +
  1567 + lsi_soft_reset(s);
  1568 +
  1569 + return s;
  1570 +}
  1571 +
... ...
... ... @@ -838,6 +838,24 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
838 838 if (pci_enabled && acpi_enabled) {
839 839 piix4_pm_init(pci_bus, piix3_devfn + 3);
840 840 }
  841 +
  842 +#if 0
  843 + /* ??? Need to figure out some way for the user to
  844 + specify SCSI devices. */
  845 + if (pci_enabled) {
  846 + void *scsi;
  847 + BlockDriverState *bdrv;
  848 +
  849 + scsi = lsi_scsi_init(pci_bus, -1);
  850 + bdrv = bdrv_new("scsidisk");
  851 + bdrv_open(bdrv, "scsi_disk.img", 0);
  852 + lsi_scsi_attach(scsi, bdrv, -1);
  853 + bdrv = bdrv_new("scsicd");
  854 + bdrv_open(bdrv, "scsi_cd.iso", 0);
  855 + bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
  856 + lsi_scsi_attach(scsi, bdrv, -1);
  857 + }
  858 +#endif
841 859 /* must be done after all PCI devices are instanciated */
842 860 /* XXX: should be done in the Bochs BIOS */
843 861 if (pci_enabled) {
... ...
hw/scsi-disk.c
... ... @@ -245,7 +245,7 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
245 245 s->buf_len = 4;
246 246 break;
247 247 case 0x12:
248   - DPRINTF("Inquiry (len %d)\n", len);
  248 + DPRINTF("Inquiry (len %d)\n", len);
249 249 if (len < 36) {
250 250 BADF("Inquiry buffer too small (%d)\n", len);
251 251 }
... ... @@ -253,12 +253,13 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
253 253 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
254 254 s->buf[0] = 5;
255 255 s->buf[1] = 0x80;
256   - memcpy(&s->buf[16], "QEMU CDROM ", 16);
  256 + memcpy(&s->buf[16], "QEMU CD-ROM ", 16);
257 257 } else {
258 258 s->buf[0] = 0;
259 259 memcpy(&s->buf[16], "QEMU HARDDISK ", 16);
260 260 }
261 261 memcpy(&s->buf[8], "QEMU ", 8);
  262 + memcpy(&s->buf[32], QEMU_VERSION, 4);
262 263 s->buf[2] = 3; /* SCSI-3 */
263 264 s->buf[3] = 2; /* Format 2 */
264 265 s->buf[4] = 32;
... ... @@ -275,18 +276,27 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
275 276 goto fail;
276 277 break;
277 278 case 0x1a:
278   - DPRINTF("Mode Sense(6) (page %d, len %d)\n", buf[2], len);
279   - memset(s->buf, 0, 4);
280   - s->buf[0] = 0x16; /* Mode data length (4 + 0x12). */
281   - s->buf[1] = 0; /* Default media type. */
282   - s->buf[2] = 0; /* Write enabled. */
283   - s->buf[3] = 0; /* Block descriptor length. */
284   - /* Caching page. */
285   - s->buf[4 + 0] = 8;
286   - s->buf[4 + 1] = 0x12;
287   - s->buf[4 + 2] = 4; /* WCE */
288   - if (len > 0x16)
289   - len = 0x16;
  279 + case 0x5a:
  280 + DPRINTF("Mode Sense (page %d, len %d)\n", buf[2], len);
  281 + if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
  282 + memset(s->buf, 0, 4);
  283 + s->buf[0] = 4; /* Mode data length. */
  284 + s->buf[1] = 0; /* Default media type. */
  285 + s->buf[2] = 0x80; /* Readonly. */
  286 + s->buf[3] = 0; /* Block descriptor length. */
  287 + } else {
  288 + memset(s->buf, 0, 0x16);
  289 + s->buf[0] = 0x16; /* Mode data length (4 + 0x12). */
  290 + s->buf[1] = 0; /* Default media type. */
  291 + s->buf[2] = 0; /* Write enabled. */
  292 + s->buf[3] = 0; /* Block descriptor length. */
  293 + /* Caching page. */
  294 + s->buf[4 + 0] = 8;
  295 + s->buf[4 + 1] = 0x12;
  296 + s->buf[4 + 2] = 4; /* WCE */
  297 + if (len > 0x16)
  298 + len = 0x16;
  299 + }
290 300 s->buf_len = len;
291 301 break;
292 302 case 0x25:
... ... @@ -317,6 +327,10 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
317 327 s->sector_count = len * s->cluster_size;
318 328 is_write = 1;
319 329 break;
  330 + case 0x35:
  331 + DPRINTF("Syncronise cache (sector %d, count %d)\n", lba, len);
  332 + /* ??? Extend block layer and use fsync to implement this. */
  333 + break;
320 334 case 0x43:
321 335 {
322 336 int start_track, format, msf, toclen;
... ...
hw/versatilepb.c
... ... @@ -343,6 +343,7 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
343 343 CPUState *env;
344 344 void *pic;
345 345 void *sic;
  346 + void *scsi_hba;
346 347 PCIBus *pci_bus;
347 348 NICInfo *nd;
348 349 int n;
... ... @@ -377,6 +378,12 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
377 378 if (usb_enabled) {
378 379 usb_ohci_init(pci_bus, 3, -1);
379 380 }
  381 + scsi_hba = lsi_scsi_init(pci_bus, -1);
  382 + for (n = 0; n < MAX_DISKS; n++) {
  383 + if (bs_table[n]) {
  384 + lsi_scsi_attach(scsi_hba, bs_table[n], n);
  385 + }
  386 + }
380 387  
381 388 pl011_init(0x101f1000, pic, 12, serial_hds[0]);
382 389 pl011_init(0x101f2000, pic, 13, serial_hds[1]);
... ...
... ... @@ -1048,6 +1048,10 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun);
1048 1048 int scsi_read_data(SCSIDevice *s, uint8_t *data, uint32_t len);
1049 1049 int scsi_write_data(SCSIDevice *s, uint8_t *data, uint32_t len);
1050 1050  
  1051 +/* lsi53c895a.c */
  1052 +void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id);
  1053 +void *lsi_scsi_init(PCIBus *bus, int devfn);
  1054 +
1051 1055 /* integratorcp.c */
1052 1056 extern QEMUMachine integratorcp926_machine;
1053 1057 extern QEMUMachine integratorcp1026_machine;
... ...