Revision 7d8406be

b/Makefile.target
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
b/hw/lsi53c895a.c
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;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff