~ahs3/+junk/cq-qemu

« back to all changes in this revision

Viewing changes to hw/esp.c

  • Committer: Al Stone
  • Date: 2012-02-09 01:17:20 UTC
  • Revision ID: albert.stone@canonical.com-20120209011720-tztl7ik3qayz80p4
first commit to bzr for qemu

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * QEMU ESP/NCR53C9x emulation
 
3
 *
 
4
 * Copyright (c) 2005-2006 Fabrice Bellard
 
5
 *
 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 
7
 * of this software and associated documentation files (the "Software"), to deal
 
8
 * in the Software without restriction, including without limitation the rights
 
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
10
 * copies of the Software, and to permit persons to whom the Software is
 
11
 * furnished to do so, subject to the following conditions:
 
12
 *
 
13
 * The above copyright notice and this permission notice shall be included in
 
14
 * all copies or substantial portions of the Software.
 
15
 *
 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
22
 * THE SOFTWARE.
 
23
 */
 
24
 
 
25
#include "sysbus.h"
 
26
#include "scsi.h"
 
27
#include "esp.h"
 
28
#include "trace.h"
 
29
 
 
30
/*
 
31
 * On Sparc32, this is the ESP (NCR53C90) part of chip STP2000 (Master I/O),
 
32
 * also produced as NCR89C100. See
 
33
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
 
34
 * and
 
35
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
 
36
 */
 
37
 
 
38
#define ESP_ERROR(fmt, ...)                                             \
 
39
    do { printf("ESP ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } while (0)
 
40
 
 
41
#define ESP_REGS 16
 
42
#define TI_BUFSZ 16
 
43
 
 
44
typedef struct ESPState ESPState;
 
45
 
 
46
struct ESPState {
 
47
    SysBusDevice busdev;
 
48
    uint8_t rregs[ESP_REGS];
 
49
    uint8_t wregs[ESP_REGS];
 
50
    qemu_irq irq;
 
51
    uint32_t it_shift;
 
52
    int32_t ti_size;
 
53
    uint32_t ti_rptr, ti_wptr;
 
54
    uint32_t status;
 
55
    uint32_t dma;
 
56
    uint8_t ti_buf[TI_BUFSZ];
 
57
    SCSIBus bus;
 
58
    SCSIDevice *current_dev;
 
59
    SCSIRequest *current_req;
 
60
    uint8_t cmdbuf[TI_BUFSZ];
 
61
    uint32_t cmdlen;
 
62
    uint32_t do_cmd;
 
63
 
 
64
    /* The amount of data left in the current DMA transfer.  */
 
65
    uint32_t dma_left;
 
66
    /* The size of the current DMA transfer.  Zero if no transfer is in
 
67
       progress.  */
 
68
    uint32_t dma_counter;
 
69
    int dma_enabled;
 
70
 
 
71
    uint32_t async_len;
 
72
    uint8_t *async_buf;
 
73
 
 
74
    ESPDMAMemoryReadWriteFunc dma_memory_read;
 
75
    ESPDMAMemoryReadWriteFunc dma_memory_write;
 
76
    void *dma_opaque;
 
77
    void (*dma_cb)(ESPState *s);
 
78
};
 
79
 
 
80
#define ESP_TCLO   0x0
 
81
#define ESP_TCMID  0x1
 
82
#define ESP_FIFO   0x2
 
83
#define ESP_CMD    0x3
 
84
#define ESP_RSTAT  0x4
 
85
#define ESP_WBUSID 0x4
 
86
#define ESP_RINTR  0x5
 
87
#define ESP_WSEL   0x5
 
88
#define ESP_RSEQ   0x6
 
89
#define ESP_WSYNTP 0x6
 
90
#define ESP_RFLAGS 0x7
 
91
#define ESP_WSYNO  0x7
 
92
#define ESP_CFG1   0x8
 
93
#define ESP_RRES1  0x9
 
94
#define ESP_WCCF   0x9
 
95
#define ESP_RRES2  0xa
 
96
#define ESP_WTEST  0xa
 
97
#define ESP_CFG2   0xb
 
98
#define ESP_CFG3   0xc
 
99
#define ESP_RES3   0xd
 
100
#define ESP_TCHI   0xe
 
101
#define ESP_RES4   0xf
 
102
 
 
103
#define CMD_DMA 0x80
 
104
#define CMD_CMD 0x7f
 
105
 
 
106
#define CMD_NOP      0x00
 
107
#define CMD_FLUSH    0x01
 
108
#define CMD_RESET    0x02
 
109
#define CMD_BUSRESET 0x03
 
110
#define CMD_TI       0x10
 
111
#define CMD_ICCS     0x11
 
112
#define CMD_MSGACC   0x12
 
113
#define CMD_PAD      0x18
 
114
#define CMD_SATN     0x1a
 
115
#define CMD_SEL      0x41
 
116
#define CMD_SELATN   0x42
 
117
#define CMD_SELATNS  0x43
 
118
#define CMD_ENSEL    0x44
 
119
 
 
120
#define STAT_DO 0x00
 
121
#define STAT_DI 0x01
 
122
#define STAT_CD 0x02
 
123
#define STAT_ST 0x03
 
124
#define STAT_MO 0x06
 
125
#define STAT_MI 0x07
 
126
#define STAT_PIO_MASK 0x06
 
127
 
 
128
#define STAT_TC 0x10
 
129
#define STAT_PE 0x20
 
130
#define STAT_GE 0x40
 
131
#define STAT_INT 0x80
 
132
 
 
133
#define BUSID_DID 0x07
 
134
 
 
135
#define INTR_FC 0x08
 
136
#define INTR_BS 0x10
 
137
#define INTR_DC 0x20
 
138
#define INTR_RST 0x80
 
139
 
 
140
#define SEQ_0 0x0
 
141
#define SEQ_CD 0x4
 
142
 
 
143
#define CFG1_RESREPT 0x40
 
144
 
 
145
#define TCHI_FAS100A 0x4
 
146
 
 
147
static void esp_raise_irq(ESPState *s)
 
148
{
 
149
    if (!(s->rregs[ESP_RSTAT] & STAT_INT)) {
 
150
        s->rregs[ESP_RSTAT] |= STAT_INT;
 
151
        qemu_irq_raise(s->irq);
 
152
        trace_esp_raise_irq();
 
153
    }
 
154
}
 
155
 
 
156
static void esp_lower_irq(ESPState *s)
 
157
{
 
158
    if (s->rregs[ESP_RSTAT] & STAT_INT) {
 
159
        s->rregs[ESP_RSTAT] &= ~STAT_INT;
 
160
        qemu_irq_lower(s->irq);
 
161
        trace_esp_lower_irq();
 
162
    }
 
163
}
 
164
 
 
165
static void esp_dma_enable(void *opaque, int irq, int level)
 
166
{
 
167
    DeviceState *d = opaque;
 
168
    ESPState *s = container_of(d, ESPState, busdev.qdev);
 
169
 
 
170
    if (level) {
 
171
        s->dma_enabled = 1;
 
172
        trace_esp_dma_enable();
 
173
        if (s->dma_cb) {
 
174
            s->dma_cb(s);
 
175
            s->dma_cb = NULL;
 
176
        }
 
177
    } else {
 
178
        trace_esp_dma_disable();
 
179
        s->dma_enabled = 0;
 
180
    }
 
181
}
 
182
 
 
183
static void esp_request_cancelled(SCSIRequest *req)
 
184
{
 
185
    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
 
186
 
 
187
    if (req == s->current_req) {
 
188
        scsi_req_unref(s->current_req);
 
189
        s->current_req = NULL;
 
190
        s->current_dev = NULL;
 
191
    }
 
192
}
 
193
 
 
194
static uint32_t get_cmd(ESPState *s, uint8_t *buf)
 
195
{
 
196
    uint32_t dmalen;
 
197
    int target;
 
198
 
 
199
    target = s->wregs[ESP_WBUSID] & BUSID_DID;
 
200
    if (s->dma) {
 
201
        dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
 
202
        s->dma_memory_read(s->dma_opaque, buf, dmalen);
 
203
    } else {
 
204
        dmalen = s->ti_size;
 
205
        memcpy(buf, s->ti_buf, dmalen);
 
206
        buf[0] = buf[2] >> 5;
 
207
    }
 
208
    trace_esp_get_cmd(dmalen, target);
 
209
 
 
210
    s->ti_size = 0;
 
211
    s->ti_rptr = 0;
 
212
    s->ti_wptr = 0;
 
213
 
 
214
    if (s->current_req) {
 
215
        /* Started a new command before the old one finished.  Cancel it.  */
 
216
        scsi_req_cancel(s->current_req);
 
217
        s->async_len = 0;
 
218
    }
 
219
 
 
220
    s->current_dev = scsi_device_find(&s->bus, 0, target, 0);
 
221
    if (!s->current_dev) {
 
222
        // No such drive
 
223
        s->rregs[ESP_RSTAT] = 0;
 
224
        s->rregs[ESP_RINTR] = INTR_DC;
 
225
        s->rregs[ESP_RSEQ] = SEQ_0;
 
226
        esp_raise_irq(s);
 
227
        return 0;
 
228
    }
 
229
    return dmalen;
 
230
}
 
231
 
 
232
static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
 
233
{
 
234
    int32_t datalen;
 
235
    int lun;
 
236
    SCSIDevice *current_lun;
 
237
 
 
238
    trace_esp_do_busid_cmd(busid);
 
239
    lun = busid & 7;
 
240
    current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, lun);
 
241
    s->current_req = scsi_req_new(current_lun, 0, lun, buf, NULL);
 
242
    datalen = scsi_req_enqueue(s->current_req);
 
243
    s->ti_size = datalen;
 
244
    if (datalen != 0) {
 
245
        s->rregs[ESP_RSTAT] = STAT_TC;
 
246
        s->dma_left = 0;
 
247
        s->dma_counter = 0;
 
248
        if (datalen > 0) {
 
249
            s->rregs[ESP_RSTAT] |= STAT_DI;
 
250
        } else {
 
251
            s->rregs[ESP_RSTAT] |= STAT_DO;
 
252
        }
 
253
        scsi_req_continue(s->current_req);
 
254
    }
 
255
    s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
 
256
    s->rregs[ESP_RSEQ] = SEQ_CD;
 
257
    esp_raise_irq(s);
 
258
}
 
259
 
 
260
static void do_cmd(ESPState *s, uint8_t *buf)
 
261
{
 
262
    uint8_t busid = buf[0];
 
263
 
 
264
    do_busid_cmd(s, &buf[1], busid);
 
265
}
 
266
 
 
267
static void handle_satn(ESPState *s)
 
268
{
 
269
    uint8_t buf[32];
 
270
    int len;
 
271
 
 
272
    if (!s->dma_enabled) {
 
273
        s->dma_cb = handle_satn;
 
274
        return;
 
275
    }
 
276
    len = get_cmd(s, buf);
 
277
    if (len)
 
278
        do_cmd(s, buf);
 
279
}
 
280
 
 
281
static void handle_s_without_atn(ESPState *s)
 
282
{
 
283
    uint8_t buf[32];
 
284
    int len;
 
285
 
 
286
    if (!s->dma_enabled) {
 
287
        s->dma_cb = handle_s_without_atn;
 
288
        return;
 
289
    }
 
290
    len = get_cmd(s, buf);
 
291
    if (len) {
 
292
        do_busid_cmd(s, buf, 0);
 
293
    }
 
294
}
 
295
 
 
296
static void handle_satn_stop(ESPState *s)
 
297
{
 
298
    if (!s->dma_enabled) {
 
299
        s->dma_cb = handle_satn_stop;
 
300
        return;
 
301
    }
 
302
    s->cmdlen = get_cmd(s, s->cmdbuf);
 
303
    if (s->cmdlen) {
 
304
        trace_esp_handle_satn_stop(s->cmdlen);
 
305
        s->do_cmd = 1;
 
306
        s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
 
307
        s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
 
308
        s->rregs[ESP_RSEQ] = SEQ_CD;
 
309
        esp_raise_irq(s);
 
310
    }
 
311
}
 
312
 
 
313
static void write_response(ESPState *s)
 
314
{
 
315
    trace_esp_write_response(s->status);
 
316
    s->ti_buf[0] = s->status;
 
317
    s->ti_buf[1] = 0;
 
318
    if (s->dma) {
 
319
        s->dma_memory_write(s->dma_opaque, s->ti_buf, 2);
 
320
        s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
 
321
        s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
 
322
        s->rregs[ESP_RSEQ] = SEQ_CD;
 
323
    } else {
 
324
        s->ti_size = 2;
 
325
        s->ti_rptr = 0;
 
326
        s->ti_wptr = 0;
 
327
        s->rregs[ESP_RFLAGS] = 2;
 
328
    }
 
329
    esp_raise_irq(s);
 
330
}
 
331
 
 
332
static void esp_dma_done(ESPState *s)
 
333
{
 
334
    s->rregs[ESP_RSTAT] |= STAT_TC;
 
335
    s->rregs[ESP_RINTR] = INTR_BS;
 
336
    s->rregs[ESP_RSEQ] = 0;
 
337
    s->rregs[ESP_RFLAGS] = 0;
 
338
    s->rregs[ESP_TCLO] = 0;
 
339
    s->rregs[ESP_TCMID] = 0;
 
340
    esp_raise_irq(s);
 
341
}
 
342
 
 
343
static void esp_do_dma(ESPState *s)
 
344
{
 
345
    uint32_t len;
 
346
    int to_device;
 
347
 
 
348
    to_device = (s->ti_size < 0);
 
349
    len = s->dma_left;
 
350
    if (s->do_cmd) {
 
351
        trace_esp_do_dma(s->cmdlen, len);
 
352
        s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
 
353
        s->ti_size = 0;
 
354
        s->cmdlen = 0;
 
355
        s->do_cmd = 0;
 
356
        do_cmd(s, s->cmdbuf);
 
357
        return;
 
358
    }
 
359
    if (s->async_len == 0) {
 
360
        /* Defer until data is available.  */
 
361
        return;
 
362
    }
 
363
    if (len > s->async_len) {
 
364
        len = s->async_len;
 
365
    }
 
366
    if (to_device) {
 
367
        s->dma_memory_read(s->dma_opaque, s->async_buf, len);
 
368
    } else {
 
369
        s->dma_memory_write(s->dma_opaque, s->async_buf, len);
 
370
    }
 
371
    s->dma_left -= len;
 
372
    s->async_buf += len;
 
373
    s->async_len -= len;
 
374
    if (to_device)
 
375
        s->ti_size += len;
 
376
    else
 
377
        s->ti_size -= len;
 
378
    if (s->async_len == 0) {
 
379
        scsi_req_continue(s->current_req);
 
380
        /* If there is still data to be read from the device then
 
381
           complete the DMA operation immediately.  Otherwise defer
 
382
           until the scsi layer has completed.  */
 
383
        if (to_device || s->dma_left != 0 || s->ti_size == 0) {
 
384
            return;
 
385
        }
 
386
    }
 
387
 
 
388
    /* Partially filled a scsi buffer. Complete immediately.  */
 
389
    esp_dma_done(s);
 
390
}
 
391
 
 
392
static void esp_command_complete(SCSIRequest *req, uint32_t status)
 
393
{
 
394
    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
 
395
 
 
396
    trace_esp_command_complete();
 
397
    if (s->ti_size != 0) {
 
398
        trace_esp_command_complete_unexpected();
 
399
    }
 
400
    s->ti_size = 0;
 
401
    s->dma_left = 0;
 
402
    s->async_len = 0;
 
403
    if (status) {
 
404
        trace_esp_command_complete_fail();
 
405
    }
 
406
    s->status = status;
 
407
    s->rregs[ESP_RSTAT] = STAT_ST;
 
408
    esp_dma_done(s);
 
409
    if (s->current_req) {
 
410
        scsi_req_unref(s->current_req);
 
411
        s->current_req = NULL;
 
412
        s->current_dev = NULL;
 
413
    }
 
414
}
 
415
 
 
416
static void esp_transfer_data(SCSIRequest *req, uint32_t len)
 
417
{
 
418
    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
 
419
 
 
420
    trace_esp_transfer_data(s->dma_left, s->ti_size);
 
421
    s->async_len = len;
 
422
    s->async_buf = scsi_req_get_buf(req);
 
423
    if (s->dma_left) {
 
424
        esp_do_dma(s);
 
425
    } else if (s->dma_counter != 0 && s->ti_size <= 0) {
 
426
        /* If this was the last part of a DMA transfer then the
 
427
           completion interrupt is deferred to here.  */
 
428
        esp_dma_done(s);
 
429
    }
 
430
}
 
431
 
 
432
static void handle_ti(ESPState *s)
 
433
{
 
434
    uint32_t dmalen, minlen;
 
435
 
 
436
    dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
 
437
    if (dmalen==0) {
 
438
      dmalen=0x10000;
 
439
    }
 
440
    s->dma_counter = dmalen;
 
441
 
 
442
    if (s->do_cmd)
 
443
        minlen = (dmalen < 32) ? dmalen : 32;
 
444
    else if (s->ti_size < 0)
 
445
        minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
 
446
    else
 
447
        minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
 
448
    trace_esp_handle_ti(minlen);
 
449
    if (s->dma) {
 
450
        s->dma_left = minlen;
 
451
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
 
452
        esp_do_dma(s);
 
453
    } else if (s->do_cmd) {
 
454
        trace_esp_handle_ti_cmd(s->cmdlen);
 
455
        s->ti_size = 0;
 
456
        s->cmdlen = 0;
 
457
        s->do_cmd = 0;
 
458
        do_cmd(s, s->cmdbuf);
 
459
        return;
 
460
    }
 
461
}
 
462
 
 
463
static void esp_hard_reset(DeviceState *d)
 
464
{
 
465
    ESPState *s = container_of(d, ESPState, busdev.qdev);
 
466
 
 
467
    memset(s->rregs, 0, ESP_REGS);
 
468
    memset(s->wregs, 0, ESP_REGS);
 
469
    s->rregs[ESP_TCHI] = TCHI_FAS100A; // Indicate fas100a
 
470
    s->ti_size = 0;
 
471
    s->ti_rptr = 0;
 
472
    s->ti_wptr = 0;
 
473
    s->dma = 0;
 
474
    s->do_cmd = 0;
 
475
    s->dma_cb = NULL;
 
476
 
 
477
    s->rregs[ESP_CFG1] = 7;
 
478
}
 
479
 
 
480
static void esp_soft_reset(DeviceState *d)
 
481
{
 
482
    ESPState *s = container_of(d, ESPState, busdev.qdev);
 
483
 
 
484
    qemu_irq_lower(s->irq);
 
485
    esp_hard_reset(d);
 
486
}
 
487
 
 
488
static void parent_esp_reset(void *opaque, int irq, int level)
 
489
{
 
490
    if (level) {
 
491
        esp_soft_reset(opaque);
 
492
    }
 
493
}
 
494
 
 
495
static void esp_gpio_demux(void *opaque, int irq, int level)
 
496
{
 
497
    switch (irq) {
 
498
    case 0:
 
499
        parent_esp_reset(opaque, irq, level);
 
500
        break;
 
501
    case 1:
 
502
        esp_dma_enable(opaque, irq, level);
 
503
        break;
 
504
    }
 
505
}
 
506
 
 
507
static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
 
508
{
 
509
    ESPState *s = opaque;
 
510
    uint32_t saddr, old_val;
 
511
 
 
512
    saddr = addr >> s->it_shift;
 
513
    trace_esp_mem_readb(saddr, s->rregs[saddr]);
 
514
    switch (saddr) {
 
515
    case ESP_FIFO:
 
516
        if (s->ti_size > 0) {
 
517
            s->ti_size--;
 
518
            if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
 
519
                /* Data out.  */
 
520
                ESP_ERROR("PIO data read not implemented\n");
 
521
                s->rregs[ESP_FIFO] = 0;
 
522
            } else {
 
523
                s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
 
524
            }
 
525
            esp_raise_irq(s);
 
526
        }
 
527
        if (s->ti_size == 0) {
 
528
            s->ti_rptr = 0;
 
529
            s->ti_wptr = 0;
 
530
        }
 
531
        break;
 
532
    case ESP_RINTR:
 
533
        /* Clear sequence step, interrupt register and all status bits
 
534
           except TC */
 
535
        old_val = s->rregs[ESP_RINTR];
 
536
        s->rregs[ESP_RINTR] = 0;
 
537
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
 
538
        s->rregs[ESP_RSEQ] = SEQ_CD;
 
539
        esp_lower_irq(s);
 
540
 
 
541
        return old_val;
 
542
    default:
 
543
        break;
 
544
    }
 
545
    return s->rregs[saddr];
 
546
}
 
547
 
 
548
static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 
549
{
 
550
    ESPState *s = opaque;
 
551
    uint32_t saddr;
 
552
 
 
553
    saddr = addr >> s->it_shift;
 
554
    trace_esp_mem_writeb(saddr, s->wregs[saddr], val);
 
555
    switch (saddr) {
 
556
    case ESP_TCLO:
 
557
    case ESP_TCMID:
 
558
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
 
559
        break;
 
560
    case ESP_FIFO:
 
561
        if (s->do_cmd) {
 
562
            s->cmdbuf[s->cmdlen++] = val & 0xff;
 
563
        } else if (s->ti_size == TI_BUFSZ - 1) {
 
564
            ESP_ERROR("fifo overrun\n");
 
565
        } else {
 
566
            s->ti_size++;
 
567
            s->ti_buf[s->ti_wptr++] = val & 0xff;
 
568
        }
 
569
        break;
 
570
    case ESP_CMD:
 
571
        s->rregs[saddr] = val;
 
572
        if (val & CMD_DMA) {
 
573
            s->dma = 1;
 
574
            /* Reload DMA counter.  */
 
575
            s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
 
576
            s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
 
577
        } else {
 
578
            s->dma = 0;
 
579
        }
 
580
        switch(val & CMD_CMD) {
 
581
        case CMD_NOP:
 
582
            trace_esp_mem_writeb_cmd_nop(val);
 
583
            break;
 
584
        case CMD_FLUSH:
 
585
            trace_esp_mem_writeb_cmd_flush(val);
 
586
            //s->ti_size = 0;
 
587
            s->rregs[ESP_RINTR] = INTR_FC;
 
588
            s->rregs[ESP_RSEQ] = 0;
 
589
            s->rregs[ESP_RFLAGS] = 0;
 
590
            break;
 
591
        case CMD_RESET:
 
592
            trace_esp_mem_writeb_cmd_reset(val);
 
593
            esp_soft_reset(&s->busdev.qdev);
 
594
            break;
 
595
        case CMD_BUSRESET:
 
596
            trace_esp_mem_writeb_cmd_bus_reset(val);
 
597
            s->rregs[ESP_RINTR] = INTR_RST;
 
598
            if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
 
599
                esp_raise_irq(s);
 
600
            }
 
601
            break;
 
602
        case CMD_TI:
 
603
            handle_ti(s);
 
604
            break;
 
605
        case CMD_ICCS:
 
606
            trace_esp_mem_writeb_cmd_iccs(val);
 
607
            write_response(s);
 
608
            s->rregs[ESP_RINTR] = INTR_FC;
 
609
            s->rregs[ESP_RSTAT] |= STAT_MI;
 
610
            break;
 
611
        case CMD_MSGACC:
 
612
            trace_esp_mem_writeb_cmd_msgacc(val);
 
613
            s->rregs[ESP_RINTR] = INTR_DC;
 
614
            s->rregs[ESP_RSEQ] = 0;
 
615
            s->rregs[ESP_RFLAGS] = 0;
 
616
            esp_raise_irq(s);
 
617
            break;
 
618
        case CMD_PAD:
 
619
            trace_esp_mem_writeb_cmd_pad(val);
 
620
            s->rregs[ESP_RSTAT] = STAT_TC;
 
621
            s->rregs[ESP_RINTR] = INTR_FC;
 
622
            s->rregs[ESP_RSEQ] = 0;
 
623
            break;
 
624
        case CMD_SATN:
 
625
            trace_esp_mem_writeb_cmd_satn(val);
 
626
            break;
 
627
        case CMD_SEL:
 
628
            trace_esp_mem_writeb_cmd_sel(val);
 
629
            handle_s_without_atn(s);
 
630
            break;
 
631
        case CMD_SELATN:
 
632
            trace_esp_mem_writeb_cmd_selatn(val);
 
633
            handle_satn(s);
 
634
            break;
 
635
        case CMD_SELATNS:
 
636
            trace_esp_mem_writeb_cmd_selatns(val);
 
637
            handle_satn_stop(s);
 
638
            break;
 
639
        case CMD_ENSEL:
 
640
            trace_esp_mem_writeb_cmd_ensel(val);
 
641
            s->rregs[ESP_RINTR] = 0;
 
642
            break;
 
643
        default:
 
644
            ESP_ERROR("Unhandled ESP command (%2.2x)\n", val);
 
645
            break;
 
646
        }
 
647
        break;
 
648
    case ESP_WBUSID ... ESP_WSYNO:
 
649
        break;
 
650
    case ESP_CFG1:
 
651
        s->rregs[saddr] = val;
 
652
        break;
 
653
    case ESP_WCCF ... ESP_WTEST:
 
654
        break;
 
655
    case ESP_CFG2 ... ESP_RES4:
 
656
        s->rregs[saddr] = val;
 
657
        break;
 
658
    default:
 
659
        ESP_ERROR("invalid write of 0x%02x at [0x%x]\n", val, saddr);
 
660
        return;
 
661
    }
 
662
    s->wregs[saddr] = val;
 
663
}
 
664
 
 
665
static CPUReadMemoryFunc * const esp_mem_read[3] = {
 
666
    esp_mem_readb,
 
667
    NULL,
 
668
    NULL,
 
669
};
 
670
 
 
671
static CPUWriteMemoryFunc * const esp_mem_write[3] = {
 
672
    esp_mem_writeb,
 
673
    NULL,
 
674
    esp_mem_writeb,
 
675
};
 
676
 
 
677
static const VMStateDescription vmstate_esp = {
 
678
    .name ="esp",
 
679
    .version_id = 3,
 
680
    .minimum_version_id = 3,
 
681
    .minimum_version_id_old = 3,
 
682
    .fields      = (VMStateField []) {
 
683
        VMSTATE_BUFFER(rregs, ESPState),
 
684
        VMSTATE_BUFFER(wregs, ESPState),
 
685
        VMSTATE_INT32(ti_size, ESPState),
 
686
        VMSTATE_UINT32(ti_rptr, ESPState),
 
687
        VMSTATE_UINT32(ti_wptr, ESPState),
 
688
        VMSTATE_BUFFER(ti_buf, ESPState),
 
689
        VMSTATE_UINT32(status, ESPState),
 
690
        VMSTATE_UINT32(dma, ESPState),
 
691
        VMSTATE_BUFFER(cmdbuf, ESPState),
 
692
        VMSTATE_UINT32(cmdlen, ESPState),
 
693
        VMSTATE_UINT32(do_cmd, ESPState),
 
694
        VMSTATE_UINT32(dma_left, ESPState),
 
695
        VMSTATE_END_OF_LIST()
 
696
    }
 
697
};
 
698
 
 
699
void esp_init(target_phys_addr_t espaddr, int it_shift,
 
700
              ESPDMAMemoryReadWriteFunc dma_memory_read,
 
701
              ESPDMAMemoryReadWriteFunc dma_memory_write,
 
702
              void *dma_opaque, qemu_irq irq, qemu_irq *reset,
 
703
              qemu_irq *dma_enable)
 
704
{
 
705
    DeviceState *dev;
 
706
    SysBusDevice *s;
 
707
    ESPState *esp;
 
708
 
 
709
    dev = qdev_create(NULL, "esp");
 
710
    esp = DO_UPCAST(ESPState, busdev.qdev, dev);
 
711
    esp->dma_memory_read = dma_memory_read;
 
712
    esp->dma_memory_write = dma_memory_write;
 
713
    esp->dma_opaque = dma_opaque;
 
714
    esp->it_shift = it_shift;
 
715
    /* XXX for now until rc4030 has been changed to use DMA enable signal */
 
716
    esp->dma_enabled = 1;
 
717
    qdev_init_nofail(dev);
 
718
    s = sysbus_from_qdev(dev);
 
719
    sysbus_connect_irq(s, 0, irq);
 
720
    sysbus_mmio_map(s, 0, espaddr);
 
721
    *reset = qdev_get_gpio_in(dev, 0);
 
722
    *dma_enable = qdev_get_gpio_in(dev, 1);
 
723
}
 
724
 
 
725
static const struct SCSIBusInfo esp_scsi_info = {
 
726
    .tcq = false,
 
727
    .max_target = ESP_MAX_DEVS,
 
728
    .max_lun = 7,
 
729
 
 
730
    .transfer_data = esp_transfer_data,
 
731
    .complete = esp_command_complete,
 
732
    .cancel = esp_request_cancelled
 
733
};
 
734
 
 
735
static int esp_init1(SysBusDevice *dev)
 
736
{
 
737
    ESPState *s = FROM_SYSBUS(ESPState, dev);
 
738
    int esp_io_memory;
 
739
 
 
740
    sysbus_init_irq(dev, &s->irq);
 
741
    assert(s->it_shift != -1);
 
742
 
 
743
    esp_io_memory = cpu_register_io_memory(esp_mem_read, esp_mem_write, s,
 
744
                                           DEVICE_NATIVE_ENDIAN);
 
745
    sysbus_init_mmio(dev, ESP_REGS << s->it_shift, esp_io_memory);
 
746
 
 
747
    qdev_init_gpio_in(&dev->qdev, esp_gpio_demux, 2);
 
748
 
 
749
    scsi_bus_new(&s->bus, &dev->qdev, &esp_scsi_info);
 
750
    return scsi_bus_legacy_handle_cmdline(&s->bus);
 
751
}
 
752
 
 
753
static SysBusDeviceInfo esp_info = {
 
754
    .init = esp_init1,
 
755
    .qdev.name  = "esp",
 
756
    .qdev.size  = sizeof(ESPState),
 
757
    .qdev.vmsd  = &vmstate_esp,
 
758
    .qdev.reset = esp_hard_reset,
 
759
    .qdev.props = (Property[]) {
 
760
        {.name = NULL}
 
761
    }
 
762
};
 
763
 
 
764
static void esp_register_devices(void)
 
765
{
 
766
    sysbus_register_withprop(&esp_info);
 
767
}
 
768
 
 
769
device_init(esp_register_devices)