~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to hw/sh7750.c

  • Committer: ths
  • Date: 2007-06-17 15:32:30 UTC
  • Revision ID: git-v1:ffb04fcf089865952592f1f8855c2848d4514a89
Allow relative paths for the interpreter prefix in linux-user emulation.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2984 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * SH7750 device
3
 
 *
4
 
 * Copyright (c) 2007 Magnus Damm
 
3
 * 
5
4
 * Copyright (c) 2005 Samuel Tardieu
6
 
 *
 
5
 * 
7
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
7
 * of this software and associated documentation files (the "Software"), to deal
9
8
 * in the Software without restriction, including without limitation the rights
24
23
 */
25
24
#include <stdio.h>
26
25
#include <assert.h>
27
 
#include "hw.h"
28
 
#include "sh.h"
29
 
#include "sysemu.h"
 
26
#include "vl.h"
30
27
#include "sh7750_regs.h"
31
28
#include "sh7750_regnames.h"
32
 
#include "sh_intc.h"
33
 
#include "exec-all.h"
34
 
#include "cpu.h"
 
29
 
 
30
typedef struct {
 
31
    uint8_t data[16];
 
32
    uint8_t length;             /* Number of characters in the FIFO */
 
33
    uint8_t write_idx;          /* Index of first character to write */
 
34
    uint8_t read_idx;           /* Index of first character to read */
 
35
} fifo;
35
36
 
36
37
#define NB_DEVICES 4
37
38
 
42
43
    uint32_t periph_freq;
43
44
    /* SDRAM controller */
44
45
    uint16_t rfcr;
 
46
    /* First serial port */
 
47
    CharDriverState *serial1;
 
48
    uint8_t scscr1;
 
49
    uint8_t scsmr1;
 
50
    uint8_t scbrr1;
 
51
    uint8_t scssr1;
 
52
    uint8_t scssr1_read;
 
53
    uint8_t sctsr1;
 
54
    uint8_t sctsr1_loaded;
 
55
    uint8_t sctdr1;
 
56
    uint8_t scrdr1;
 
57
    /* Second serial port */
 
58
    CharDriverState *serial2;
 
59
    uint16_t sclsr2;
 
60
    uint16_t scscr2;
 
61
    uint16_t scfcr2;
 
62
    uint16_t scfsr2;
 
63
    uint16_t scsmr2;
 
64
    uint8_t scbrr2;
 
65
    fifo serial2_receive_fifo;
 
66
    fifo serial2_transmit_fifo;
 
67
    /* Timers */
 
68
    uint8_t tstr;
 
69
    /* Timer 0 */
 
70
    QEMUTimer *timer0;
 
71
    uint16_t tcr0;
 
72
    uint32_t tcor0;
 
73
    uint32_t tcnt0;
45
74
    /* IO ports */
46
75
    uint16_t gpioic;
47
76
    uint32_t pctra;
57
86
    uint16_t periph_pdtrb;      /* Imposed by the peripherals */
58
87
    uint16_t periph_portdirb;   /* Direction seen from the peripherals */
59
88
    sh7750_io_device *devices[NB_DEVICES];      /* External peripherals */
60
 
 
61
 
    uint16_t icr;
62
89
    /* Cache */
63
90
    uint32_t ccr;
64
 
 
65
 
    struct intc_desc intc;
66
91
} SH7750State;
67
92
 
 
93
/**********************************************************************
 
94
 Timers
 
95
**********************************************************************/
 
96
 
 
97
/* XXXXX At this time, timer0 works in underflow only mode, that is
 
98
   the value of tcnt0 is read at alarm computation time and cannot
 
99
   be read back by the guest OS */
 
100
 
 
101
static void start_timer0(SH7750State * s)
 
102
{
 
103
    uint64_t now, next, prescaler;
 
104
 
 
105
    if ((s->tcr0 & 6) == 6) {
 
106
        fprintf(stderr, "rtc clock for timer 0 not supported\n");
 
107
        assert(0);
 
108
    }
 
109
 
 
110
    if ((s->tcr0 & 7) == 5) {
 
111
        fprintf(stderr, "timer 0 configuration not supported\n");
 
112
        assert(0);
 
113
    }
 
114
 
 
115
    if ((s->tcr0 & 4) == 4)
 
116
        prescaler = 1024;
 
117
    else
 
118
        prescaler = 4 << (s->tcr0 & 3);
 
119
 
 
120
    now = qemu_get_clock(vm_clock);
 
121
    /* XXXXX */
 
122
    next =
 
123
        now + muldiv64(prescaler * s->tcnt0, ticks_per_sec,
 
124
                       s->periph_freq);
 
125
    if (next == now)
 
126
        next = now + 1;
 
127
    fprintf(stderr, "now=%016" PRIx64 ", next=%016" PRIx64 "\n", now, next);
 
128
    fprintf(stderr, "timer will underflow in %f seconds\n",
 
129
            (float) (next - now) / (float) ticks_per_sec);
 
130
 
 
131
    qemu_mod_timer(s->timer0, next);
 
132
}
 
133
 
 
134
static void timer_start_changed(SH7750State * s)
 
135
{
 
136
    if (s->tstr & SH7750_TSTR_STR0) {
 
137
        start_timer0(s);
 
138
    } else {
 
139
        fprintf(stderr, "timer 0 is stopped\n");
 
140
        qemu_del_timer(s->timer0);
 
141
    }
 
142
}
 
143
 
 
144
static void timer0_cb(void *opaque)
 
145
{
 
146
    SH7750State *s = opaque;
 
147
 
 
148
    s->tcnt0 = (uint32_t) 0;    /* XXXXX */
 
149
    if (--s->tcnt0 == (uint32_t) - 1) {
 
150
        fprintf(stderr, "timer 0 underflow\n");
 
151
        s->tcnt0 = s->tcor0;
 
152
        s->tcr0 |= SH7750_TCR_UNF;
 
153
        if (s->tcr0 & SH7750_TCR_UNIE) {
 
154
            fprintf(stderr,
 
155
                    "interrupt generation for timer 0 not supported\n");
 
156
            assert(0);
 
157
        }
 
158
    }
 
159
    start_timer0(s);
 
160
}
 
161
 
 
162
static void init_timers(SH7750State * s)
 
163
{
 
164
    s->tcor0 = 0xffffffff;
 
165
    s->tcnt0 = 0xffffffff;
 
166
    s->timer0 = qemu_new_timer(vm_clock, &timer0_cb, s);
 
167
}
 
168
 
 
169
/**********************************************************************
 
170
 First serial port
 
171
**********************************************************************/
 
172
 
 
173
static int serial1_can_receive(void *opaque)
 
174
{
 
175
    SH7750State *s = opaque;
 
176
 
 
177
    return s->scscr1 & SH7750_SCSCR_RE;
 
178
}
 
179
 
 
180
static void serial1_receive_char(SH7750State * s, uint8_t c)
 
181
{
 
182
    if (s->scssr1 & SH7750_SCSSR1_RDRF) {
 
183
        s->scssr1 |= SH7750_SCSSR1_ORER;
 
184
        return;
 
185
    }
 
186
 
 
187
    s->scrdr1 = c;
 
188
    s->scssr1 |= SH7750_SCSSR1_RDRF;
 
189
}
 
190
 
 
191
static void serial1_receive(void *opaque, const uint8_t * buf, int size)
 
192
{
 
193
    SH7750State *s = opaque;
 
194
    int i;
 
195
 
 
196
    for (i = 0; i < size; i++) {
 
197
        serial1_receive_char(s, buf[i]);
 
198
    }
 
199
}
 
200
 
 
201
static void serial1_event(void *opaque, int event)
 
202
{
 
203
    assert(0);
 
204
}
 
205
 
 
206
static void serial1_maybe_send(SH7750State * s)
 
207
{
 
208
    uint8_t c;
 
209
 
 
210
    if (s->scssr1 & SH7750_SCSSR1_TDRE)
 
211
        return;
 
212
    c = s->sctdr1;
 
213
    s->scssr1 |= SH7750_SCSSR1_TDRE | SH7750_SCSSR1_TEND;
 
214
    if (s->scscr1 & SH7750_SCSCR_TIE) {
 
215
        fprintf(stderr, "interrupts for serial port 1 not implemented\n");
 
216
        assert(0);
 
217
    }
 
218
    /* XXXXX Check for errors in write */
 
219
    qemu_chr_write(s->serial1, &c, 1);
 
220
}
 
221
 
 
222
static void serial1_change_scssr1(SH7750State * s, uint8_t mem_value)
 
223
{
 
224
    uint8_t new_flags;
 
225
 
 
226
    /* If transmit disable, TDRE and TEND stays up */
 
227
    if ((s->scscr1 & SH7750_SCSCR_TE) == 0) {
 
228
        mem_value |= SH7750_SCSSR1_TDRE | SH7750_SCSSR1_TEND;
 
229
    }
 
230
 
 
231
    /* Only clear bits which have been read before and do not set any bit
 
232
       in the flags */
 
233
    new_flags = s->scssr1 & ~s->scssr1_read;    /* Preserve unread flags */
 
234
    new_flags &= mem_value | ~s->scssr1_read;   /* Clear read flags */
 
235
 
 
236
    s->scssr1 = (new_flags & 0xf8) | (mem_value & 1);
 
237
    s->scssr1_read &= mem_value;
 
238
 
 
239
    /* If TDRE has been cleared, TEND will also be cleared */
 
240
    if ((s->scssr1 & SH7750_SCSSR1_TDRE) == 0) {
 
241
        s->scssr1 &= ~SH7750_SCSSR1_TEND;
 
242
    }
 
243
 
 
244
    /* Check for transmission to start */
 
245
    serial1_maybe_send(s);
 
246
}
 
247
 
 
248
static void serial1_update_parameters(SH7750State * s)
 
249
{
 
250
    QEMUSerialSetParams ssp;
 
251
 
 
252
    if (s->scsmr1 & SH7750_SCSMR_CHR_7)
 
253
        ssp.data_bits = 7;
 
254
    else
 
255
        ssp.data_bits = 8;
 
256
    if (s->scsmr1 & SH7750_SCSMR_PE) {
 
257
        if (s->scsmr1 & SH7750_SCSMR_PM_ODD)
 
258
            ssp.parity = 'O';
 
259
        else
 
260
            ssp.parity = 'E';
 
261
    } else
 
262
        ssp.parity = 'N';
 
263
    if (s->scsmr1 & SH7750_SCSMR_STOP_2)
 
264
        ssp.stop_bits = 2;
 
265
    else
 
266
        ssp.stop_bits = 1;
 
267
    fprintf(stderr, "SCSMR1=%04x SCBRR1=%02x\n", s->scsmr1, s->scbrr1);
 
268
    ssp.speed = s->periph_freq /
 
269
        (32 * s->scbrr1 * (1 << (2 * (s->scsmr1 & 3)))) - 1;
 
270
    fprintf(stderr, "data bits=%d, stop bits=%d, parity=%c, speed=%d\n",
 
271
            ssp.data_bits, ssp.stop_bits, ssp.parity, ssp.speed);
 
272
    qemu_chr_ioctl(s->serial1, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
 
273
}
 
274
 
 
275
static void scscr1_changed(SH7750State * s)
 
276
{
 
277
    if (s->scscr1 & (SH7750_SCSCR_TE | SH7750_SCSCR_RE)) {
 
278
        if (!s->serial1) {
 
279
            fprintf(stderr, "serial port 1 not bound to anything\n");
 
280
            assert(0);
 
281
        }
 
282
        serial1_update_parameters(s);
 
283
    }
 
284
    if ((s->scscr1 & SH7750_SCSCR_RE) == 0) {
 
285
        s->scssr1 |= SH7750_SCSSR1_TDRE;
 
286
    }
 
287
}
 
288
 
 
289
static void init_serial1(SH7750State * s, int serial_nb)
 
290
{
 
291
    CharDriverState *chr;
 
292
 
 
293
    s->scssr1 = 0x84;
 
294
    chr = serial_hds[serial_nb];
 
295
    if (!chr) {
 
296
        fprintf(stderr,
 
297
                "no serial port associated to SH7750 first serial port\n");
 
298
        return;
 
299
    }
 
300
 
 
301
    s->serial1 = chr;
 
302
    qemu_chr_add_handlers(chr, serial1_can_receive,
 
303
                          serial1_receive, serial1_event, s);
 
304
}
 
305
 
 
306
/**********************************************************************
 
307
 Second serial port
 
308
**********************************************************************/
 
309
 
 
310
static int serial2_can_receive(void *opaque)
 
311
{
 
312
    SH7750State *s = opaque;
 
313
    static uint8_t max_fifo_size[] = { 15, 1, 4, 6, 8, 10, 12, 14 };
 
314
 
 
315
    return s->serial2_receive_fifo.length <
 
316
        max_fifo_size[(s->scfcr2 >> 9) & 7];
 
317
}
 
318
 
 
319
static void serial2_adjust_receive_flags(SH7750State * s)
 
320
{
 
321
    static uint8_t max_fifo_size[] = { 1, 4, 8, 14 };
 
322
 
 
323
    /* XXXXX Add interrupt generation */
 
324
    if (s->serial2_receive_fifo.length >=
 
325
        max_fifo_size[(s->scfcr2 >> 7) & 3]) {
 
326
        s->scfsr2 |= SH7750_SCFSR2_RDF;
 
327
        s->scfsr2 &= ~SH7750_SCFSR2_DR;
 
328
    } else {
 
329
        s->scfsr2 &= ~SH7750_SCFSR2_RDF;
 
330
        if (s->serial2_receive_fifo.length > 0)
 
331
            s->scfsr2 |= SH7750_SCFSR2_DR;
 
332
        else
 
333
            s->scfsr2 &= ~SH7750_SCFSR2_DR;
 
334
    }
 
335
}
 
336
 
 
337
static void serial2_append_char(SH7750State * s, uint8_t c)
 
338
{
 
339
    if (s->serial2_receive_fifo.length == 16) {
 
340
        /* Overflow */
 
341
        s->sclsr2 |= SH7750_SCLSR2_ORER;
 
342
        return;
 
343
    }
 
344
 
 
345
    s->serial2_receive_fifo.data[s->serial2_receive_fifo.write_idx++] = c;
 
346
    s->serial2_receive_fifo.length++;
 
347
    serial2_adjust_receive_flags(s);
 
348
}
 
349
 
 
350
static void serial2_receive(void *opaque, const uint8_t * buf, int size)
 
351
{
 
352
    SH7750State *s = opaque;
 
353
    int i;
 
354
 
 
355
    for (i = 0; i < size; i++)
 
356
        serial2_append_char(s, buf[i]);
 
357
}
 
358
 
 
359
static void serial2_event(void *opaque, int event)
 
360
{
 
361
    /* XXXXX */
 
362
    assert(0);
 
363
}
 
364
 
 
365
static void serial2_update_parameters(SH7750State * s)
 
366
{
 
367
    QEMUSerialSetParams ssp;
 
368
 
 
369
    if (s->scsmr2 & SH7750_SCSMR_CHR_7)
 
370
        ssp.data_bits = 7;
 
371
    else
 
372
        ssp.data_bits = 8;
 
373
    if (s->scsmr2 & SH7750_SCSMR_PE) {
 
374
        if (s->scsmr2 & SH7750_SCSMR_PM_ODD)
 
375
            ssp.parity = 'O';
 
376
        else
 
377
            ssp.parity = 'E';
 
378
    } else
 
379
        ssp.parity = 'N';
 
380
    if (s->scsmr2 & SH7750_SCSMR_STOP_2)
 
381
        ssp.stop_bits = 2;
 
382
    else
 
383
        ssp.stop_bits = 1;
 
384
    fprintf(stderr, "SCSMR2=%04x SCBRR2=%02x\n", s->scsmr2, s->scbrr2);
 
385
    ssp.speed = s->periph_freq /
 
386
        (32 * s->scbrr2 * (1 << (2 * (s->scsmr2 & 3)))) - 1;
 
387
    fprintf(stderr, "data bits=%d, stop bits=%d, parity=%c, speed=%d\n",
 
388
            ssp.data_bits, ssp.stop_bits, ssp.parity, ssp.speed);
 
389
    qemu_chr_ioctl(s->serial2, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
 
390
}
 
391
 
 
392
static void scscr2_changed(SH7750State * s)
 
393
{
 
394
    if (s->scscr2 & (SH7750_SCSCR_TE | SH7750_SCSCR_RE)) {
 
395
        if (!s->serial2) {
 
396
            fprintf(stderr, "serial port 2 not bound to anything\n");
 
397
            assert(0);
 
398
        }
 
399
        serial2_update_parameters(s);
 
400
    }
 
401
}
 
402
 
 
403
static void init_serial2(SH7750State * s, int serial_nb)
 
404
{
 
405
    CharDriverState *chr;
 
406
 
 
407
    s->scfsr2 = 0x0060;
 
408
 
 
409
    chr = serial_hds[serial_nb];
 
410
    if (!chr) {
 
411
        fprintf(stderr,
 
412
                "no serial port associated to SH7750 second serial port\n");
 
413
        return;
 
414
    }
 
415
 
 
416
    s->serial2 = chr;
 
417
    qemu_chr_add_handlers(chr, serial2_can_receive,
 
418
                          serial2_receive, serial1_event, s);
 
419
}
 
420
 
 
421
static void init_serial_ports(SH7750State * s)
 
422
{
 
423
    init_serial1(s, 0);
 
424
    init_serial2(s, 1);
 
425
}
68
426
 
69
427
/**********************************************************************
70
428
 I/O ports
184
542
 
185
543
static void error_access(const char *kind, target_phys_addr_t addr)
186
544
{
187
 
    fprintf(stderr, "%s to %s (0x" TARGET_FMT_plx ") not supported\n",
 
545
    fprintf(stderr, "%s to %s (0x%08x) not supported\n",
188
546
            kind, regname(addr), addr);
189
547
}
190
548
 
191
549
static void ignore_access(const char *kind, target_phys_addr_t addr)
192
550
{
193
 
    fprintf(stderr, "%s to %s (0x" TARGET_FMT_plx ") ignored\n",
 
551
    fprintf(stderr, "%s to %s (0x%08x) ignored\n",
194
552
            kind, regname(addr), addr);
195
553
}
196
554
 
197
555
static uint32_t sh7750_mem_readb(void *opaque, target_phys_addr_t addr)
198
556
{
 
557
    SH7750State *s = opaque;
 
558
    uint8_t r;
 
559
 
199
560
    switch (addr) {
 
561
    case SH7750_SCSSR1_A7:
 
562
        r = s->scssr1;
 
563
        s->scssr1_read |= r;
 
564
        return s->scssr1;
 
565
    case SH7750_SCRDR1_A7:
 
566
        s->scssr1 &= ~SH7750_SCSSR1_RDRF;
 
567
        return s->scrdr1;
200
568
    default:
201
569
        error_access("byte read", addr);
202
570
        assert(0);
206
574
static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr)
207
575
{
208
576
    SH7750State *s = opaque;
 
577
    uint16_t r;
209
578
 
210
579
    switch (addr) {
211
 
    case SH7750_FRQCR_A7:
212
 
        return 0;
213
580
    case SH7750_RFCR_A7:
214
581
        fprintf(stderr,
215
582
                "Read access to refresh count register, incrementing\n");
216
583
        return s->rfcr++;
 
584
    case SH7750_TCR0_A7:
 
585
        return s->tcr0;
 
586
    case SH7750_SCLSR2_A7:
 
587
        /* Read and clear overflow bit */
 
588
        r = s->sclsr2;
 
589
        s->sclsr2 = 0;
 
590
        return r;
 
591
    case SH7750_SCSFR2_A7:
 
592
        return s->scfsr2;
217
593
    case SH7750_PDTRA_A7:
218
594
        return porta_lines(s);
219
595
    case SH7750_PDTRB_A7:
220
596
        return portb_lines(s);
221
 
    case 0x1fd00000:
222
 
        return s->icr;
223
597
    default:
224
598
        error_access("word read", addr);
225
599
        assert(0);
249
623
        return s->cpu->intevt;
250
624
    case SH7750_CCR_A7:
251
625
        return s->ccr;
252
 
    case 0x1f000030:            /* Processor version */
253
 
        return s->cpu->pvr;
254
 
    case 0x1f000040:            /* Cache version */
255
 
        return s->cpu->cvr;
256
 
    case 0x1f000044:            /* Processor revision */
257
 
        return s->cpu->prr;
 
626
    case 0x1f000030:            /* Processor version PVR */
 
627
        return 0x00050000;      /* SH7750R */
 
628
    case 0x1f000040:            /* Processor version CVR */
 
629
        return 0x00110000;      /* Minimum caches */
 
630
    case 0x1f000044:            /* Processor version PRR */
 
631
        return 0x00000100;      /* SH7750R */
258
632
    default:
259
633
        error_access("long read", addr);
260
634
        assert(0);
264
638
static void sh7750_mem_writeb(void *opaque, target_phys_addr_t addr,
265
639
                              uint32_t mem_value)
266
640
{
 
641
    SH7750State *s = opaque;
 
642
 
267
643
    switch (addr) {
268
644
        /* PRECHARGE ? XXXXX */
269
645
    case SH7750_PRECHARGE0_A7:
270
646
    case SH7750_PRECHARGE1_A7:
271
647
        ignore_access("byte write", addr);
272
648
        return;
 
649
    case SH7750_SCBRR2_A7:
 
650
        s->scbrr2 = mem_value;
 
651
        return;
 
652
    case SH7750_TSTR_A7:
 
653
        s->tstr = mem_value;
 
654
        timer_start_changed(s);
 
655
        return;
 
656
    case SH7750_SCSCR1_A7:
 
657
        s->scscr1 = mem_value;
 
658
        scscr1_changed(s);
 
659
        return;
 
660
    case SH7750_SCSMR1_A7:
 
661
        s->scsmr1 = mem_value;
 
662
        return;
 
663
    case SH7750_SCBRR1_A7:
 
664
        s->scbrr1 = mem_value;
 
665
        return;
 
666
    case SH7750_SCTDR1_A7:
 
667
        s->scssr1 &= ~SH7750_SCSSR1_TEND;
 
668
        s->sctdr1 = mem_value;
 
669
        return;
 
670
    case SH7750_SCSSR1_A7:
 
671
        serial1_change_scssr1(s, mem_value);
 
672
        return;
273
673
    default:
274
674
        error_access("byte write", addr);
275
675
        assert(0);
284
684
 
285
685
    switch (addr) {
286
686
        /* SDRAM controller */
 
687
    case SH7750_SCBRR1_A7:
 
688
    case SH7750_SCBRR2_A7:
287
689
    case SH7750_BCR2_A7:
288
690
    case SH7750_BCR3_A7:
289
691
    case SH7750_RTCOR_A7:
306
708
        fprintf(stderr, "Write access to refresh count register\n");
307
709
        s->rfcr = mem_value;
308
710
        return;
 
711
    case SH7750_SCLSR2_A7:
 
712
        s->sclsr2 = mem_value;
 
713
        return;
 
714
    case SH7750_SCSCR2_A7:
 
715
        s->scscr2 = mem_value;
 
716
        scscr2_changed(s);
 
717
        return;
 
718
    case SH7750_SCFCR2_A7:
 
719
        s->scfcr2 = mem_value;
 
720
        return;
 
721
    case SH7750_SCSMR2_A7:
 
722
        s->scsmr2 = mem_value;
 
723
        return;
 
724
    case SH7750_TCR0_A7:
 
725
        s->tcr0 = mem_value;
 
726
        return;
309
727
    case SH7750_GPIOIC_A7:
310
728
        s->gpioic = mem_value;
311
729
        if (mem_value != 0) {
313
731
            assert(0);
314
732
        }
315
733
        return;
316
 
    case 0x1fd00000:
317
 
        s->icr = mem_value;
318
 
        return;
319
734
    default:
320
735
        error_access("word write", addr);
321
736
        assert(0);
353
768
        s->portpullupb = portpullup(mem_value);
354
769
        portb_changed(s, temp);
355
770
        return;
 
771
    case SH7750_TCNT0_A7:
 
772
        s->tcnt0 = mem_value & 0xf;
 
773
        return;
356
774
    case SH7750_MMUCR_A7:
357
775
        s->cpu->mmucr = mem_value;
358
776
        return;
359
777
    case SH7750_PTEH_A7:
360
 
        /* If asid changes, clear all registered tlb entries. */
361
 
        if ((s->cpu->pteh & 0xff) != (mem_value & 0xff))
362
 
            tlb_flush(s->cpu, 1);
363
778
        s->cpu->pteh = mem_value;
364
779
        return;
365
780
    case SH7750_PTEL_A7:
366
781
        s->cpu->ptel = mem_value;
367
782
        return;
368
 
    case SH7750_PTEA_A7:
369
 
        s->cpu->ptea = mem_value & 0x0000000f;
370
 
        return;
371
783
    case SH7750_TTB_A7:
372
784
        s->cpu->ttb = mem_value;
373
785
        return;
404
816
    sh7750_mem_writel
405
817
};
406
818
 
407
 
/* sh775x interrupt controller tables for sh_intc.c
408
 
 * stolen from linux/arch/sh/kernel/cpu/sh4/setup-sh7750.c
409
 
 */
410
 
 
411
 
enum {
412
 
        UNUSED = 0,
413
 
 
414
 
        /* interrupt sources */
415
 
        IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */
416
 
        HUDI, GPIOI,
417
 
        DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3,
418
 
        DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7,
419
 
        DMAC_DMAE,
420
 
        PCIC0_PCISERR, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
421
 
        PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3,
422
 
        TMU3, TMU4, TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
423
 
        RTC_ATI, RTC_PRI, RTC_CUI,
424
 
        SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI,
425
 
        SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI,
426
 
        WDT,
427
 
        REF_RCMI, REF_ROVI,
428
 
 
429
 
        /* interrupt groups */
430
 
        DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
431
 
 
432
 
        NR_SOURCES,
433
 
};
434
 
 
435
 
static struct intc_vect vectors[] = {
436
 
        INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
437
 
        INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
438
 
        INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
439
 
        INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
440
 
        INTC_VECT(RTC_CUI, 0x4c0),
441
 
        INTC_VECT(SCI1_ERI, 0x4e0), INTC_VECT(SCI1_RXI, 0x500),
442
 
        INTC_VECT(SCI1_TXI, 0x520), INTC_VECT(SCI1_TEI, 0x540),
443
 
        INTC_VECT(SCIF_ERI, 0x700), INTC_VECT(SCIF_RXI, 0x720),
444
 
        INTC_VECT(SCIF_BRI, 0x740), INTC_VECT(SCIF_TXI, 0x760),
445
 
        INTC_VECT(WDT, 0x560),
446
 
        INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0),
447
 
};
448
 
 
449
 
static struct intc_group groups[] = {
450
 
        INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
451
 
        INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
452
 
        INTC_GROUP(SCI1, SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI),
453
 
        INTC_GROUP(SCIF, SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI),
454
 
        INTC_GROUP(REF, REF_RCMI, REF_ROVI),
455
 
};
456
 
 
457
 
static struct intc_prio_reg prio_registers[] = {
458
 
        { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
459
 
        { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } },
460
 
        { 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } },
461
 
        { 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } },
462
 
        { 0xfe080000, 0, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0,
463
 
                                                 TMU4, TMU3,
464
 
                                                 PCIC1, PCIC0_PCISERR } },
465
 
};
466
 
 
467
 
/* SH7750, SH7750S, SH7751 and SH7091 all have 4-channel DMA controllers */
468
 
 
469
 
static struct intc_vect vectors_dma4[] = {
470
 
        INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
471
 
        INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
472
 
        INTC_VECT(DMAC_DMAE, 0x6c0),
473
 
};
474
 
 
475
 
static struct intc_group groups_dma4[] = {
476
 
        INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
477
 
                   DMAC_DMTE3, DMAC_DMAE),
478
 
};
479
 
 
480
 
/* SH7750R and SH7751R both have 8-channel DMA controllers */
481
 
 
482
 
static struct intc_vect vectors_dma8[] = {
483
 
        INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
484
 
        INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
485
 
        INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0),
486
 
        INTC_VECT(DMAC_DMTE6, 0x7c0), INTC_VECT(DMAC_DMTE7, 0x7e0),
487
 
        INTC_VECT(DMAC_DMAE, 0x6c0),
488
 
};
489
 
 
490
 
static struct intc_group groups_dma8[] = {
491
 
        INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
492
 
                   DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5,
493
 
                   DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE),
494
 
};
495
 
 
496
 
/* SH7750R, SH7751 and SH7751R all have two extra timer channels */
497
 
 
498
 
static struct intc_vect vectors_tmu34[] = {
499
 
        INTC_VECT(TMU3, 0xb00), INTC_VECT(TMU4, 0xb80),
500
 
};
501
 
 
502
 
static struct intc_mask_reg mask_registers[] = {
503
 
        { 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */
504
 
          { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
505
 
            0, 0, 0, 0, 0, 0, TMU4, TMU3,
506
 
            PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
507
 
            PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2,
508
 
            PCIC1_PCIDMA3, PCIC0_PCISERR } },
509
 
};
510
 
 
511
 
/* SH7750S, SH7750R, SH7751 and SH7751R all have IRLM priority registers */
512
 
 
513
 
static struct intc_vect vectors_irlm[] = {
514
 
        INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0),
515
 
        INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360),
516
 
};
517
 
 
518
 
/* SH7751 and SH7751R both have PCI */
519
 
 
520
 
static struct intc_vect vectors_pci[] = {
521
 
        INTC_VECT(PCIC0_PCISERR, 0xa00), INTC_VECT(PCIC1_PCIERR, 0xae0),
522
 
        INTC_VECT(PCIC1_PCIPWDWN, 0xac0), INTC_VECT(PCIC1_PCIPWON, 0xaa0),
523
 
        INTC_VECT(PCIC1_PCIDMA0, 0xa80), INTC_VECT(PCIC1_PCIDMA1, 0xa60),
524
 
        INTC_VECT(PCIC1_PCIDMA2, 0xa40), INTC_VECT(PCIC1_PCIDMA3, 0xa20),
525
 
};
526
 
 
527
 
static struct intc_group groups_pci[] = {
528
 
        INTC_GROUP(PCIC1, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
529
 
                   PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3),
530
 
};
531
 
 
532
 
/**********************************************************************
533
 
 Memory mapped cache and TLB
534
 
**********************************************************************/
535
 
 
536
 
#define MM_REGION_MASK   0x07000000
537
 
#define MM_ICACHE_ADDR   (0)
538
 
#define MM_ICACHE_DATA   (1)
539
 
#define MM_ITLB_ADDR     (2)
540
 
#define MM_ITLB_DATA     (3)
541
 
#define MM_OCACHE_ADDR   (4)
542
 
#define MM_OCACHE_DATA   (5)
543
 
#define MM_UTLB_ADDR     (6)
544
 
#define MM_UTLB_DATA     (7)
545
 
#define MM_REGION_TYPE(addr)  ((addr & MM_REGION_MASK) >> 24)
546
 
 
547
 
static uint32_t invalid_read(void *opaque, target_phys_addr_t addr)
548
 
{
549
 
    assert(0);
550
 
 
551
 
    return 0;
552
 
}
553
 
 
554
 
static uint32_t sh7750_mmct_readl(void *opaque, target_phys_addr_t addr)
555
 
{
556
 
    uint32_t ret = 0;
557
 
 
558
 
    switch (MM_REGION_TYPE(addr)) {
559
 
    case MM_ICACHE_ADDR:
560
 
    case MM_ICACHE_DATA:
561
 
        /* do nothing */
562
 
        break;
563
 
    case MM_ITLB_ADDR:
564
 
    case MM_ITLB_DATA:
565
 
        /* XXXXX */
566
 
        assert(0);
567
 
        break;
568
 
    case MM_OCACHE_ADDR:
569
 
    case MM_OCACHE_DATA:
570
 
        /* do nothing */
571
 
        break;
572
 
    case MM_UTLB_ADDR:
573
 
    case MM_UTLB_DATA:
574
 
        /* XXXXX */
575
 
        assert(0);
576
 
        break;
577
 
    default:
578
 
        assert(0);
579
 
    }
580
 
 
581
 
    return ret;
582
 
}
583
 
 
584
 
static void invalid_write(void *opaque, target_phys_addr_t addr,
585
 
                          uint32_t mem_value)
586
 
{
587
 
    assert(0);
588
 
}
589
 
 
590
 
static void sh7750_mmct_writel(void *opaque, target_phys_addr_t addr,
591
 
                                uint32_t mem_value)
592
 
{
593
 
    SH7750State *s = opaque;
594
 
 
595
 
    switch (MM_REGION_TYPE(addr)) {
596
 
    case MM_ICACHE_ADDR:
597
 
    case MM_ICACHE_DATA:
598
 
        /* do nothing */
599
 
        break;
600
 
    case MM_ITLB_ADDR:
601
 
    case MM_ITLB_DATA:
602
 
        /* XXXXX */
603
 
        assert(0);
604
 
        break;
605
 
    case MM_OCACHE_ADDR:
606
 
    case MM_OCACHE_DATA:
607
 
        /* do nothing */
608
 
        break;
609
 
    case MM_UTLB_ADDR:
610
 
        cpu_sh4_write_mmaped_utlb_addr(s->cpu, addr, mem_value);
611
 
        break;
612
 
    case MM_UTLB_DATA:
613
 
        /* XXXXX */
614
 
        assert(0);
615
 
        break;
616
 
    default:
617
 
        assert(0);
618
 
        break;
619
 
    }
620
 
}
621
 
 
622
 
static CPUReadMemoryFunc *sh7750_mmct_read[] = {
623
 
    invalid_read,
624
 
    invalid_read,
625
 
    sh7750_mmct_readl
626
 
};
627
 
 
628
 
static CPUWriteMemoryFunc *sh7750_mmct_write[] = {
629
 
    invalid_write,
630
 
    invalid_write,
631
 
    sh7750_mmct_writel
632
 
};
633
 
 
634
819
SH7750State *sh7750_init(CPUSH4State * cpu)
635
820
{
636
821
    SH7750State *s;
637
822
    int sh7750_io_memory;
638
 
    int sh7750_mm_cache_and_tlb; /* memory mapped cache and tlb */
639
823
 
640
824
    s = qemu_mallocz(sizeof(SH7750State));
641
825
    s->cpu = cpu;
644
828
                                              sh7750_mem_read,
645
829
                                              sh7750_mem_write, s);
646
830
    cpu_register_physical_memory(0x1c000000, 0x04000000, sh7750_io_memory);
647
 
 
648
 
    sh7750_mm_cache_and_tlb = cpu_register_io_memory(0,
649
 
                                                     sh7750_mmct_read,
650
 
                                                     sh7750_mmct_write, s);
651
 
    cpu_register_physical_memory(0xf0000000, 0x08000000,
652
 
                                 sh7750_mm_cache_and_tlb);
653
 
 
654
 
    sh_intc_init(&s->intc, NR_SOURCES,
655
 
                 _INTC_ARRAY(mask_registers),
656
 
                 _INTC_ARRAY(prio_registers));
657
 
 
658
 
    sh_intc_register_sources(&s->intc,
659
 
                             _INTC_ARRAY(vectors),
660
 
                             _INTC_ARRAY(groups));
661
 
 
662
 
    cpu->intc_handle = &s->intc;
663
 
 
664
 
    sh_serial_init(0x1fe00000, 0, s->periph_freq, serial_hds[0],
665
 
                   sh_intc_source(&s->intc, SCI1_ERI),
666
 
                   sh_intc_source(&s->intc, SCI1_RXI),
667
 
                   sh_intc_source(&s->intc, SCI1_TXI),
668
 
                   sh_intc_source(&s->intc, SCI1_TEI),
669
 
                   NULL);
670
 
    sh_serial_init(0x1fe80000, SH_SERIAL_FEAT_SCIF,
671
 
                   s->periph_freq, serial_hds[1],
672
 
                   sh_intc_source(&s->intc, SCIF_ERI),
673
 
                   sh_intc_source(&s->intc, SCIF_RXI),
674
 
                   sh_intc_source(&s->intc, SCIF_TXI),
675
 
                   NULL,
676
 
                   sh_intc_source(&s->intc, SCIF_BRI));
677
 
 
678
 
    tmu012_init(0x1fd80000,
679
 
                TMU012_FEAT_TOCR | TMU012_FEAT_3CHAN | TMU012_FEAT_EXTCLK,
680
 
                s->periph_freq,
681
 
                sh_intc_source(&s->intc, TMU0),
682
 
                sh_intc_source(&s->intc, TMU1),
683
 
                sh_intc_source(&s->intc, TMU2_TUNI),
684
 
                sh_intc_source(&s->intc, TMU2_TICPI));
685
 
 
686
 
    if (cpu->id & (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7751)) {
687
 
        sh_intc_register_sources(&s->intc,
688
 
                                 _INTC_ARRAY(vectors_dma4),
689
 
                                 _INTC_ARRAY(groups_dma4));
690
 
    }
691
 
 
692
 
    if (cpu->id & (SH_CPU_SH7750R | SH_CPU_SH7751R)) {
693
 
        sh_intc_register_sources(&s->intc,
694
 
                                 _INTC_ARRAY(vectors_dma8),
695
 
                                 _INTC_ARRAY(groups_dma8));
696
 
    }
697
 
 
698
 
    if (cpu->id & (SH_CPU_SH7750R | SH_CPU_SH7751 | SH_CPU_SH7751R)) {
699
 
        sh_intc_register_sources(&s->intc,
700
 
                                 _INTC_ARRAY(vectors_tmu34),
701
 
                                 NULL, 0);
702
 
        tmu012_init(0x1e100000, 0, s->periph_freq,
703
 
                    sh_intc_source(&s->intc, TMU3),
704
 
                    sh_intc_source(&s->intc, TMU4),
705
 
                    NULL, NULL);
706
 
    }
707
 
 
708
 
    if (cpu->id & (SH_CPU_SH7751_ALL)) {
709
 
        sh_intc_register_sources(&s->intc,
710
 
                                 _INTC_ARRAY(vectors_pci),
711
 
                                 _INTC_ARRAY(groups_pci));
712
 
    }
713
 
 
714
 
    if (cpu->id & (SH_CPU_SH7750S | SH_CPU_SH7750R | SH_CPU_SH7751_ALL)) {
715
 
        sh_intc_register_sources(&s->intc,
716
 
                                 _INTC_ARRAY(vectors_irlm),
717
 
                                 NULL, 0);
718
 
    }
719
 
 
 
831
    init_timers(s);
 
832
    init_serial_ports(s);
720
833
    return s;
721
834
}