1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13: #include "hw.h"
14: #include "pci.h"
15: #include "scsi-disk.h"
16:
17:
18:
19:
20: #ifdef DEBUG_LSI
21: #define DPRINTF(fmt, args...) \
22: do { printf("lsi_scsi: " fmt , ##args); } while (0)
23: #define BADF(fmt, args...) \
24: do { fprintf(stderr, "lsi_scsi: error: " fmt , ##args); exit(1);} while (0)
25: #else
26: #define DPRINTF(fmt, args...) do {} while(0)
27: #define BADF(fmt, args...) \
28: do { fprintf(stderr, "lsi_scsi: error: " fmt , ##args);} while (0)
29: #endif
30:
31: #define LSI_SCNTL0_TRG 0x01
32: #define LSI_SCNTL0_AAP 0x02
33: #define LSI_SCNTL0_EPC 0x08
34: #define LSI_SCNTL0_WATN 0x10
35: #define LSI_SCNTL0_START 0x20
36:
37: #define LSI_SCNTL1_SST 0x01
38: #define LSI_SCNTL1_IARB 0x02
39: #define LSI_SCNTL1_AESP 0x04
40: #define LSI_SCNTL1_RST 0x08
41: #define LSI_SCNTL1_CON 0x10
42: #define LSI_SCNTL1_DHP 0x20
43: #define LSI_SCNTL1_ADB 0x40
44: #define LSI_SCNTL1_EXC 0x80
45:
46: #define LSI_SCNTL2_WSR 0x01
47: #define LSI_SCNTL2_VUE0 0x02
48: #define LSI_SCNTL2_VUE1 0x04
49: #define LSI_SCNTL2_WSS 0x08
50: #define LSI_SCNTL2_SLPHBEN 0x10
51: #define LSI_SCNTL2_SLPMD 0x20
52: #define LSI_SCNTL2_CHM 0x40
53: #define LSI_SCNTL2_SDU 0x80
54:
55: #define LSI_ISTAT0_DIP 0x01
56: #define LSI_ISTAT0_SIP 0x02
57: #define LSI_ISTAT0_INTF 0x04
58: #define LSI_ISTAT0_CON 0x08
59: #define LSI_ISTAT0_SEM 0x10
60: #define LSI_ISTAT0_SIGP 0x20
61: #define LSI_ISTAT0_SRST 0x40
62: #define LSI_ISTAT0_ABRT 0x80
63:
64: #define LSI_ISTAT1_SI 0x01
65: #define LSI_ISTAT1_SRUN 0x02
66: #define LSI_ISTAT1_FLSH 0x04
67:
68: #define LSI_SSTAT0_SDP0 0x01
69: #define LSI_SSTAT0_RST 0x02
70: #define LSI_SSTAT0_WOA 0x04
71: #define LSI_SSTAT0_LOA 0x08
72: #define LSI_SSTAT0_AIP 0x10
73: #define LSI_SSTAT0_OLF 0x20
74: #define LSI_SSTAT0_ORF 0x40
75: #define LSI_SSTAT0_ILF 0x80
76:
77: #define LSI_SIST0_PAR 0x01
78: #define LSI_SIST0_RST 0x02
79: #define LSI_SIST0_UDC 0x04
80: #define LSI_SIST0_SGE 0x08
81: #define LSI_SIST0_RSL 0x10
82: #define LSI_SIST0_SEL 0x20
83: #define LSI_SIST0_CMP 0x40
84: #define LSI_SIST0_MA 0x80
85:
86: #define LSI_SIST1_HTH 0x01
87: #define LSI_SIST1_GEN 0x02
88: #define LSI_SIST1_STO 0x04
89: #define LSI_SIST1_SBMC 0x10
90:
91: #define LSI_SOCL_IO 0x01
92: #define LSI_SOCL_CD 0x02
93: #define LSI_SOCL_MSG 0x04
94: #define LSI_SOCL_ATN 0x08
95: #define LSI_SOCL_SEL 0x10
96: #define LSI_SOCL_BSY 0x20
97: #define LSI_SOCL_ACK 0x40
98: #define LSI_SOCL_REQ 0x80
99:
100: #define LSI_DSTAT_IID 0x01
101: #define LSI_DSTAT_SIR 0x04
102: #define LSI_DSTAT_SSI 0x08
103: #define LSI_DSTAT_ABRT 0x10
104: #define LSI_DSTAT_BF 0x20
105: #define LSI_DSTAT_MDPE 0x40
106: #define LSI_DSTAT_DFE 0x80
107:
108: #define LSI_DCNTL_COM 0x01
109: #define LSI_DCNTL_IRQD 0x02
110: #define LSI_DCNTL_STD 0x04
111: #define LSI_DCNTL_IRQM 0x08
112: #define LSI_DCNTL_SSM 0x10
113: #define LSI_DCNTL_PFEN 0x20
114: #define LSI_DCNTL_PFF 0x40
115: #define LSI_DCNTL_CLSE 0x80
116:
117: #define LSI_DMODE_MAN 0x01
118: #define LSI_DMODE_BOF 0x02
119: #define LSI_DMODE_ERMP 0x04
120: #define LSI_DMODE_ERL 0x08
121: #define LSI_DMODE_DIOM 0x10
122: #define LSI_DMODE_SIOM 0x20
123:
124: #define LSI_CTEST2_DACK 0x01
125: #define LSI_CTEST2_DREQ 0x02
126: #define LSI_CTEST2_TEOP 0x04
127: #define LSI_CTEST2_PCICIE 0x08
128: #define LSI_CTEST2_CM 0x10
129: #define LSI_CTEST2_CIO 0x20
130: #define LSI_CTEST2_SIGP 0x40
131: #define LSI_CTEST2_DDIR 0x80
132:
133: #define LSI_CTEST5_BL2 0x04
134: #define LSI_CTEST5_DDIR 0x08
135: #define LSI_CTEST5_MASR 0x10
136: #define LSI_CTEST5_DFSN 0x20
137: #define LSI_CTEST5_BBCK 0x40
138: #define LSI_CTEST5_ADCK 0x80
139:
140: #define LSI_CCNTL0_DILS 0x01
141: #define LSI_CCNTL0_DISFC 0x10
142: #define LSI_CCNTL0_ENNDJ 0x20
143: #define LSI_CCNTL0_PMJCTL 0x40
144: #define LSI_CCNTL0_ENPMJ 0x80
145:
146: #define PHASE_DO 0
147: #define PHASE_DI 1
148: #define PHASE_CMD 2
149: #define PHASE_ST 3
150: #define PHASE_MO 6
151: #define PHASE_MI 7
152: #define PHASE_MASK 7
153:
154:
155: #define LSI_MAX_MSGIN_LEN 8
156:
157:
158: #define LSI_TAG_VALID (1 << 16)
159:
160: typedef struct {
161: uint32_t tag;
162: uint32_t pending;
163: int out;
164: } lsi_queue;
165:
166: typedef struct {
167: PCIDevice pci_dev;
168: int mmio_io_addr;
169: int ram_io_addr;
170: uint32_t script_ram_base;
171:
172: int carry;
173: int sense;
174:
175:
176: int msg_action;
177: int msg_len;
178: uint8_t msg[LSI_MAX_MSGIN_LEN];
179:
180:
181:
182:
183: int waiting;
184: SCSIDevice *scsi_dev[LSI_MAX_DEVS];
185: SCSIDevice *current_dev;
186: int current_lun;
187:
188: uint32_t current_tag;
189: uint32_t current_dma_len;
190: int command_complete;
191: uint8_t *dma_buf;
192: lsi_queue *queue;
193: int queue_len;
194: int active_commands;
195:
196: uint32_t dsa;
197: uint32_t temp;
198: uint32_t dnad;
199: uint32_t dbc;
200: uint8_t istat0;
201: uint8_t istat1;
202: uint8_t dcmd;
203: uint8_t dstat;
204: uint8_t dien;
205: uint8_t sist0;
206: uint8_t sist1;
207: uint8_t sien0;
208: uint8_t sien1;
209: uint8_t mbox0;
210: uint8_t mbox1;
211: uint8_t dfifo;
212: uint8_t ctest3;
213: uint8_t ctest4;
214: uint8_t ctest5;
215: uint8_t ccntl0;
216: uint8_t ccntl1;
217: uint32_t dsp;
218: uint32_t dsps;
219: uint8_t dmode;
220: uint8_t dcntl;
221: uint8_t scntl0;
222: uint8_t scntl1;
223: uint8_t scntl2;
224: uint8_t scntl3;
225: uint8_t sstat0;
226: uint8_t sstat1;
227: uint8_t scid;
228: uint8_t sxfer;
229: uint8_t socl;
230: uint8_t sdid;
231: uint8_t ssid;
232: uint8_t sfbr;
233: uint8_t stest1;
234: uint8_t stest2;
235: uint8_t stest3;
236: uint8_t sidl;
237: uint8_t stime0;
238: uint8_t respid0;
239: uint8_t respid1;
240: uint32_t mmrs;
241: uint32_t mmws;
242: uint32_t sfs;
243: uint32_t drs;
244: uint32_t sbms;
245: uint32_t dmbs;
246: uint32_t dnad64;
247: uint32_t pmjad1;
248: uint32_t pmjad2;
249: uint32_t rbc;
250: uint32_t ua;
251: uint32_t ia;
252: uint32_t sbc;
253: uint32_t csbc;
254: uint32_t scratch[18];
255:
256:
257: uint32_t script_ram[2048];
258: } LSIState;
259:
260: static void lsi_soft_reset(LSIState *s)
261: {
262: DPRINTF("Reset\n");
263: s->carry = 0;
264:
265: s->waiting = 0;
266: s->dsa = 0;
267: s->dnad = 0;
268: s->dbc = 0;
269: s->temp = 0;
270: memset(s->scratch, 0, sizeof(s->scratch));
271: s->istat0 = 0;
272: s->istat1 = 0;
273: s->dcmd = 0;
274: s->dstat = 0;
275: s->dien = 0;
276: s->sist0 = 0;
277: s->sist1 = 0;
278: s->sien0 = 0;
279: s->sien1 = 0;
280: s->mbox0 = 0;
281: s->mbox1 = 0;
282: s->dfifo = 0;
283: s->ctest3 = 0;
284: s->ctest4 = 0;
285: s->ctest5 = 0;
286: s->ccntl0 = 0;
287: s->ccntl1 = 0;
288: s->dsp = 0;
289: s->dsps = 0;
290: s->dmode = 0;
291: s->dcntl = 0;
292: s->scntl0 = 0xc0;
293: s->scntl1 = 0;
294: s->scntl2 = 0;
295: s->scntl3 = 0;
296: s->sstat0 = 0;
297: s->sstat1 = 0;
298: s->scid = 7;
299: s->sxfer = 0;
300: s->socl = 0;
301: s->stest1 = 0;
302: s->stest2 = 0;
303: s->stest3 = 0;
304: s->sidl = 0;
305: s->stime0 = 0;
306: s->respid0 = 0x80;
307: s->respid1 = 0;
308: s->mmrs = 0;
309: s->mmws = 0;
310: s->sfs = 0;
311: s->drs = 0;
312: s->sbms = 0;
313: s->dmbs = 0;
314: s->dnad64 = 0;
315: s->pmjad1 = 0;
316: s->pmjad2 = 0;
317: s->rbc = 0;
318: s->ua = 0;
319: s->ia = 0;
320: s->sbc = 0;
321: s->csbc = 0;
322: }
323:
324: static uint8_t lsi_reg_readb(LSIState *s, int offset);
325: static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val);
326: static void lsi_execute_script(LSIState *s);
327:
328: static inline uint32_t read_dword(LSIState *s, uint32_t addr)
329: {
330: uint32_t buf;
331:
332:
333: if ((addr & 0xffffe000) == s->script_ram_base) {
334: return s->script_ram[(addr & 0x1fff) >> 2];
335: }
336: cpu_physical_memory_read(addr, (uint8_t *)&buf, 4);
337: return cpu_to_le32(buf);
338: }
339:
340: static void lsi_stop_script(LSIState *s)
341: {
342: s->istat1 &= ~LSI_ISTAT1_SRUN;
343: }
344:
345: static void lsi_update_irq(LSIState *s)
346: {
347: int level;
348: static int last_level;
349:
350:
351:
352:
353: level = 0;
354: if (s->dstat) {
355: if (s->dstat & s->dien)
356: level = 1;
357: s->istat0 |= LSI_ISTAT0_DIP;
358: } else {
359: s->istat0 &= ~LSI_ISTAT0_DIP;
360: }
361:
362: if (s->sist0 || s->sist1) {
363: if ((s->sist0 & s->sien0) || (s->sist1 & s->sien1))
364: level = 1;
365: s->istat0 |= LSI_ISTAT0_SIP;
366: } else {
367: s->istat0 &= ~LSI_ISTAT0_SIP;
368: }
369: if (s->istat0 & LSI_ISTAT0_INTF)
370: level = 1;
371:
372: if (level != last_level) {
373: DPRINTF("Update IRQ level %d dstat %02x sist %02x%02x\n",
374: level, s->dstat, s->sist1, s->sist0);
375: last_level = level;
376: }
377: qemu_set_irq(s->pci_dev.irq[0], level);
378: }
379:
380:
381: static void lsi_script_scsi_interrupt(LSIState *s, int stat0, int stat1)
382: {
383: uint32_t mask0;
384: uint32_t mask1;
385:
386: DPRINTF("SCSI Interrupt 0x%02x%02x prev 0x%02x%02x\n",
387: stat1, stat0, s->sist1, s->sist0);
388: s->sist0 |= stat0;
389: s->sist1 |= stat1;
390:
391:
392:
393: mask0 = s->sien0 | ~(LSI_SIST0_CMP | LSI_SIST0_SEL | LSI_SIST0_RSL);
394: mask1 = s->sien1 | ~(LSI_SIST1_GEN | LSI_SIST1_HTH);
395: mask1 &= ~LSI_SIST1_STO;
396: if (s->sist0 & mask0 || s->sist1 & mask1) {
397: lsi_stop_script(s);
398: }
399: lsi_update_irq(s);
400: }
401:
402:
403: static void lsi_script_dma_interrupt(LSIState *s, int stat)
404: {
405: DPRINTF("DMA Interrupt 0x%x prev 0x%x\n", stat, s->dstat);
406: s->dstat |= stat;
407: lsi_update_irq(s);
408: lsi_stop_script(s);
409: }
410:
411: static inline void lsi_set_phase(LSIState *s, int phase)
412: {
413: s->sstat1 = (s->sstat1 & ~PHASE_MASK) | phase;
414: }
415:
416: static void lsi_bad_phase(LSIState *s, int out, int new_phase)
417: {
418:
419: if (s->ccntl0 & LSI_CCNTL0_ENPMJ) {
420: if ((s->ccntl0 & LSI_CCNTL0_PMJCTL) || out) {
421: s->dsp = s->pmjad1;
422: } else {
423: s->dsp = s->pmjad2;
424: }
425: DPRINTF("Data phase mismatch jump to %08x\n", s->dsp);
426: } else {
427: DPRINTF("Phase mismatch interrupt\n");
428: lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
429: lsi_stop_script(s);
430: }
431: lsi_set_phase(s, new_phase);
432: }
433:
434:
435:
436: static void lsi_resume_script(LSIState *s)
437: {
438: if (s->waiting != 2) {
439: s->waiting = 0;
440: lsi_execute_script(s);
441: } else {
442: s->waiting = 0;
443: }
444: }
445:
446:
447: static void lsi_do_dma(LSIState *s, int out)
448: {
449: uint32_t count;
450: uint32_t addr;
451:
452: if (!s->current_dma_len) {
453:
454: DPRINTF("DMA no data available\n");
455: return;
456: }
457:
458: count = s->dbc;
459: if (count > s->current_dma_len)
460: count = s->current_dma_len;
461: DPRINTF("DMA addr=0x%08x len=%d\n", s->dnad, count);
462:
463: addr = s->dnad;
464: s->csbc += count;
465: s->dnad += count;
466: s->dbc -= count;
467:
468: if (s->dma_buf == NULL) {
469: s->dma_buf = s->current_dev->get_buf(s->current_dev,
470: s->current_tag);
471: }
472:
473:
474: if (out) {
475: cpu_physical_memory_read(addr, s->dma_buf, count);
476: } else {
477: cpu_physical_memory_write(addr, s->dma_buf, count);
478: }
479: s->current_dma_len -= count;
480: if (s->current_dma_len == 0) {
481: s->dma_buf = NULL;
482: if (out) {
483:
484: s->current_dev->write_data(s->current_dev, s->current_tag);
485: } else {
486:
487: s->current_dev->read_data(s->current_dev, s->current_tag);
488: }
489: } else {
490: s->dma_buf += count;
491: lsi_resume_script(s);
492: }
493: }
494:
495:
496:
497: static void lsi_queue_command(LSIState *s)
498: {
499: lsi_queue *p;
500:
501: DPRINTF("Queueing tag=0x%x\n", s->current_tag);
502: if (s->queue_len == s->active_commands) {
503: s->queue_len++;
504: s->queue = realloc(s->queue, s->queue_len * sizeof(lsi_queue));
505: }
506: p = &s->queue[s->active_commands++];
507: p->tag = s->current_tag;
508: p->pending = 0;
509: p->out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
510: }
511:
512:
513: static void lsi_add_msg_byte(LSIState *s, uint8_t data)
514: {
515: if (s->msg_len >= LSI_MAX_MSGIN_LEN) {
516: BADF("MSG IN data too long\n");
517: } else {
518: DPRINTF("MSG IN 0x%02x\n", data);
519: s->msg[s->msg_len++] = data;
520: }
521: }
522:
523:
524: static void lsi_reselect(LSIState *s, uint32_t tag)
525: {
526: lsi_queue *p;
527: int n;
528: int id;
529:
530: p = NULL;
531: for (n = 0; n < s->active_commands; n++) {
532: p = &s->queue[n];
533: if (p->tag == tag)
534: break;
535: }
536: if (n == s->active_commands) {
537: BADF("Reselected non-existant command tag=0x%x\n", tag);
538: return;
539: }
540: id = (tag >> 8) & 0xf;
541: s->ssid = id | 0x80;
542: DPRINTF("Reselected target %d\n", id);
543: s->current_dev = s->scsi_dev[id];
544: s->current_tag = tag;
545: s->scntl1