Statistics
| Branch: | Revision:

root / hw / sh7750.c @ 26a76461

History | View | Annotate | Download (20.6 kB)

1
/*
2
 * SH7750 device
3
 * 
4
 * Copyright (c) 2005 Samuel Tardieu
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
#include <stdio.h>
25
#include <assert.h>
26
#include "vl.h"
27
#include "sh7750_regs.h"
28
#include "sh7750_regnames.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;
36

    
37
#define NB_DEVICES 4
38

    
39
typedef struct SH7750State {
40
    /* CPU */
41
    CPUSH4State *cpu;
42
    /* Peripheral frequency in Hz */
43
    uint32_t periph_freq;
44
    /* SDRAM controller */
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;
74
    /* IO ports */
75
    uint16_t gpioic;
76
    uint32_t pctra;
77
    uint32_t pctrb;
78
    uint16_t portdira;                /* Cached */
79
    uint16_t portpullupa;        /* Cached */
80
    uint16_t portdirb;                /* Cached */
81
    uint16_t portpullupb;        /* Cached */
82
    uint16_t pdtra;
83
    uint16_t pdtrb;
84
    uint16_t periph_pdtra;        /* Imposed by the peripherals */
85
    uint16_t periph_portdira;        /* Direction seen from the peripherals */
86
    uint16_t periph_pdtrb;        /* Imposed by the peripherals */
87
    uint16_t periph_portdirb;        /* Direction seen from the peripherals */
88
    sh7750_io_device *devices[NB_DEVICES];        /* External peripherals */
89
    /* Cache */
90
    uint32_t ccr;
91
} SH7750State;
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_read_handler(chr, serial1_can_receive,
303
                              serial1_receive, s);
304
    qemu_chr_add_event_handler(chr, serial1_event);
305
}
306

    
307
/**********************************************************************
308
 Second serial port
309
**********************************************************************/
310

    
311
static int serial2_can_receive(void *opaque)
312
{
313
    SH7750State *s = opaque;
314
    static uint8_t max_fifo_size[] = { 15, 1, 4, 6, 8, 10, 12, 14 };
315

    
316
    return s->serial2_receive_fifo.length <
317
        max_fifo_size[(s->scfcr2 >> 9) & 7];
318
}
319

    
320
static void serial2_adjust_receive_flags(SH7750State * s)
321
{
322
    static uint8_t max_fifo_size[] = { 1, 4, 8, 14 };
323

    
324
    /* XXXXX Add interrupt generation */
325
    if (s->serial2_receive_fifo.length >=
326
        max_fifo_size[(s->scfcr2 >> 7) & 3]) {
327
        s->scfsr2 |= SH7750_SCFSR2_RDF;
328
        s->scfsr2 &= ~SH7750_SCFSR2_DR;
329
    } else {
330
        s->scfsr2 &= ~SH7750_SCFSR2_RDF;
331
        if (s->serial2_receive_fifo.length > 0)
332
            s->scfsr2 |= SH7750_SCFSR2_DR;
333
        else
334
            s->scfsr2 &= ~SH7750_SCFSR2_DR;
335
    }
336
}
337

    
338
static void serial2_append_char(SH7750State * s, uint8_t c)
339
{
340
    if (s->serial2_receive_fifo.length == 16) {
341
        /* Overflow */
342
        s->sclsr2 |= SH7750_SCLSR2_ORER;
343
        return;
344
    }
345

    
346
    s->serial2_receive_fifo.data[s->serial2_receive_fifo.write_idx++] = c;
347
    s->serial2_receive_fifo.length++;
348
    serial2_adjust_receive_flags(s);
349
}
350

    
351
static void serial2_receive(void *opaque, const uint8_t * buf, int size)
352
{
353
    SH7750State *s = opaque;
354
    int i;
355

    
356
    for (i = 0; i < size; i++)
357
        serial2_append_char(s, buf[i]);
358
}
359

    
360
static void serial2_event(void *opaque, int event)
361
{
362
    /* XXXXX */
363
    assert(0);
364
}
365

    
366
static void serial2_update_parameters(SH7750State * s)
367
{
368
    QEMUSerialSetParams ssp;
369

    
370
    if (s->scsmr2 & SH7750_SCSMR_CHR_7)
371
        ssp.data_bits = 7;
372
    else
373
        ssp.data_bits = 8;
374
    if (s->scsmr2 & SH7750_SCSMR_PE) {
375
        if (s->scsmr2 & SH7750_SCSMR_PM_ODD)
376
            ssp.parity = 'O';
377
        else
378
            ssp.parity = 'E';
379
    } else
380
        ssp.parity = 'N';
381
    if (s->scsmr2 & SH7750_SCSMR_STOP_2)
382
        ssp.stop_bits = 2;
383
    else
384
        ssp.stop_bits = 1;
385
    fprintf(stderr, "SCSMR2=%04x SCBRR2=%02x\n", s->scsmr2, s->scbrr2);
386
    ssp.speed = s->periph_freq /
387
        (32 * s->scbrr2 * (1 << (2 * (s->scsmr2 & 3)))) - 1;
388
    fprintf(stderr, "data bits=%d, stop bits=%d, parity=%c, speed=%d\n",
389
            ssp.data_bits, ssp.stop_bits, ssp.parity, ssp.speed);
390
    qemu_chr_ioctl(s->serial2, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
391
}
392

    
393
static void scscr2_changed(SH7750State * s)
394
{
395
    if (s->scscr2 & (SH7750_SCSCR_TE | SH7750_SCSCR_RE)) {
396
        if (!s->serial2) {
397
            fprintf(stderr, "serial port 2 not bound to anything\n");
398
            assert(0);
399
        }
400
        serial2_update_parameters(s);
401
    }
402
}
403

    
404
static void init_serial2(SH7750State * s, int serial_nb)
405
{
406
    CharDriverState *chr;
407

    
408
    s->scfsr2 = 0x0060;
409

    
410
    chr = serial_hds[serial_nb];
411
    if (!chr) {
412
        fprintf(stderr,
413
                "no serial port associated to SH7750 second serial port\n");
414
        return;
415
    }
416

    
417
    s->serial2 = chr;
418
    qemu_chr_add_read_handler(chr, serial2_can_receive,
419
                              serial2_receive, s);
420
    qemu_chr_add_event_handler(chr, serial2_event);
421
}
422

    
423
static void init_serial_ports(SH7750State * s)
424
{
425
    init_serial1(s, 0);
426
    init_serial2(s, 1);
427
}
428

    
429
/**********************************************************************
430
 I/O ports
431
**********************************************************************/
432

    
433
int sh7750_register_io_device(SH7750State * s, sh7750_io_device * device)
434
{
435
    int i;
436

    
437
    for (i = 0; i < NB_DEVICES; i++) {
438
        if (s->devices[i] == NULL) {
439
            s->devices[i] = device;
440
            return 0;
441
        }
442
    }
443
    return -1;
444
}
445

    
446
static uint16_t portdir(uint32_t v)
447
{
448
#define EVENPORTMASK(n) ((v & (1<<((n)<<1))) >> (n))
449
    return
450
        EVENPORTMASK(15) | EVENPORTMASK(14) | EVENPORTMASK(13) |
451
        EVENPORTMASK(12) | EVENPORTMASK(11) | EVENPORTMASK(10) |
452
        EVENPORTMASK(9) | EVENPORTMASK(8) | EVENPORTMASK(7) |
453
        EVENPORTMASK(6) | EVENPORTMASK(5) | EVENPORTMASK(4) |
454
        EVENPORTMASK(3) | EVENPORTMASK(2) | EVENPORTMASK(1) |
455
        EVENPORTMASK(0);
456
}
457

    
458
static uint16_t portpullup(uint32_t v)
459
{
460
#define ODDPORTMASK(n) ((v & (1<<(((n)<<1)+1))) >> (n))
461
    return
462
        ODDPORTMASK(15) | ODDPORTMASK(14) | ODDPORTMASK(13) |
463
        ODDPORTMASK(12) | ODDPORTMASK(11) | ODDPORTMASK(10) |
464
        ODDPORTMASK(9) | ODDPORTMASK(8) | ODDPORTMASK(7) | ODDPORTMASK(6) |
465
        ODDPORTMASK(5) | ODDPORTMASK(4) | ODDPORTMASK(3) | ODDPORTMASK(2) |
466
        ODDPORTMASK(1) | ODDPORTMASK(0);
467
}
468

    
469
static uint16_t porta_lines(SH7750State * s)
470
{
471
    return (s->portdira & s->pdtra) |        /* CPU */
472
        (s->periph_portdira & s->periph_pdtra) |        /* Peripherals */
473
        (~(s->portdira | s->periph_portdira) & s->portpullupa);        /* Pullups */
474
}
475

    
476
static uint16_t portb_lines(SH7750State * s)
477
{
478
    return (s->portdirb & s->pdtrb) |        /* CPU */
479
        (s->periph_portdirb & s->periph_pdtrb) |        /* Peripherals */
480
        (~(s->portdirb | s->periph_portdirb) & s->portpullupb);        /* Pullups */
481
}
482

    
483
static void gen_port_interrupts(SH7750State * s)
484
{
485
    /* XXXXX interrupts not generated */
486
}
487

    
488
static void porta_changed(SH7750State * s, uint16_t prev)
489
{
490
    uint16_t currenta, changes;
491
    int i, r = 0;
492

    
493
#if 0
494
    fprintf(stderr, "porta changed from 0x%04x to 0x%04x\n",
495
            prev, porta_lines(s));
496
    fprintf(stderr, "pdtra=0x%04x, pctra=0x%08x\n", s->pdtra, s->pctra);
497
#endif
498
    currenta = porta_lines(s);
499
    if (currenta == prev)
500
        return;
501
    changes = currenta ^ prev;
502

    
503
    for (i = 0; i < NB_DEVICES; i++) {
504
        if (s->devices[i] && (s->devices[i]->portamask_trigger & changes)) {
505
            r |= s->devices[i]->port_change_cb(currenta, portb_lines(s),
506
                                               &s->periph_pdtra,
507
                                               &s->periph_portdira,
508
                                               &s->periph_pdtrb,
509
                                               &s->periph_portdirb);
510
        }
511
    }
512

    
513
    if (r)
514
        gen_port_interrupts(s);
515
}
516

    
517
static void portb_changed(SH7750State * s, uint16_t prev)
518
{
519
    uint16_t currentb, changes;
520
    int i, r = 0;
521

    
522
    currentb = portb_lines(s);
523
    if (currentb == prev)
524
        return;
525
    changes = currentb ^ prev;
526

    
527
    for (i = 0; i < NB_DEVICES; i++) {
528
        if (s->devices[i] && (s->devices[i]->portbmask_trigger & changes)) {
529
            r |= s->devices[i]->port_change_cb(portb_lines(s), currentb,
530
                                               &s->periph_pdtra,
531
                                               &s->periph_portdira,
532
                                               &s->periph_pdtrb,
533
                                               &s->periph_portdirb);
534
        }
535
    }
536

    
537
    if (r)
538
        gen_port_interrupts(s);
539
}
540

    
541
/**********************************************************************
542
 Memory
543
**********************************************************************/
544

    
545
static void error_access(const char *kind, target_phys_addr_t addr)
546
{
547
    fprintf(stderr, "%s to %s (0x%08x) not supported\n",
548
            kind, regname(addr), addr);
549
}
550

    
551
static void ignore_access(const char *kind, target_phys_addr_t addr)
552
{
553
    fprintf(stderr, "%s to %s (0x%08x) ignored\n",
554
            kind, regname(addr), addr);
555
}
556

    
557
static uint32_t sh7750_mem_readb(void *opaque, target_phys_addr_t addr)
558
{
559
    SH7750State *s = opaque;
560
    uint8_t r;
561

    
562
    switch (addr) {
563
    case SH7750_SCSSR1_A7:
564
        r = s->scssr1;
565
        s->scssr1_read |= r;
566
        return s->scssr1;
567
    case SH7750_SCRDR1_A7:
568
        s->scssr1 &= ~SH7750_SCSSR1_RDRF;
569
        return s->scrdr1;
570
    default:
571
        error_access("byte read", addr);
572
        assert(0);
573
    }
574
}
575

    
576
static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr)
577
{
578
    SH7750State *s = opaque;
579
    uint16_t r;
580

    
581
    switch (addr) {
582
    case SH7750_RFCR_A7:
583
        fprintf(stderr,
584
                "Read access to refresh count register, incrementing\n");
585
        return s->rfcr++;
586
    case SH7750_TCR0_A7:
587
        return s->tcr0;
588
    case SH7750_SCLSR2_A7:
589
        /* Read and clear overflow bit */
590
        r = s->sclsr2;
591
        s->sclsr2 = 0;
592
        return r;
593
    case SH7750_SCSFR2_A7:
594
        return s->scfsr2;
595
    case SH7750_PDTRA_A7:
596
        return porta_lines(s);
597
    case SH7750_PDTRB_A7:
598
        return portb_lines(s);
599
    default:
600
        error_access("word read", addr);
601
        assert(0);
602
    }
603
}
604

    
605
static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr)
606
{
607
    SH7750State *s = opaque;
608

    
609
    switch (addr) {
610
    case SH7750_MMUCR_A7:
611
        return s->cpu->mmucr;
612
    case SH7750_PTEH_A7:
613
        return s->cpu->pteh;
614
    case SH7750_PTEL_A7:
615
        return s->cpu->ptel;
616
    case SH7750_TTB_A7:
617
        return s->cpu->ttb;
618
    case SH7750_TEA_A7:
619
        return s->cpu->tea;
620
    case SH7750_TRA_A7:
621
        return s->cpu->tra;
622
    case SH7750_EXPEVT_A7:
623
        return s->cpu->expevt;
624
    case SH7750_INTEVT_A7:
625
        return s->cpu->intevt;
626
    case SH7750_CCR_A7:
627
        return s->ccr;
628
    case 0x1f000030:                /* Processor version PVR */
629
        return 0x00050000;        /* SH7750R */
630
    case 0x1f000040:                /* Processor version CVR */
631
        return 0x00110000;        /* Minimum caches */
632
    case 0x1f000044:                /* Processor version PRR */
633
        return 0x00000100;        /* SH7750R */
634
    default:
635
        error_access("long read", addr);
636
        assert(0);
637
    }
638
}
639

    
640
static void sh7750_mem_writeb(void *opaque, target_phys_addr_t addr,
641
                              uint32_t mem_value)
642
{
643
    SH7750State *s = opaque;
644

    
645
    switch (addr) {
646
        /* PRECHARGE ? XXXXX */
647
    case SH7750_PRECHARGE0_A7:
648
    case SH7750_PRECHARGE1_A7:
649
        ignore_access("byte write", addr);
650
        return;
651
    case SH7750_SCBRR2_A7:
652
        s->scbrr2 = mem_value;
653
        return;
654
    case SH7750_TSTR_A7:
655
        s->tstr = mem_value;
656
        timer_start_changed(s);
657
        return;
658
    case SH7750_SCSCR1_A7:
659
        s->scscr1 = mem_value;
660
        scscr1_changed(s);
661
        return;
662
    case SH7750_SCSMR1_A7:
663
        s->scsmr1 = mem_value;
664
        return;
665
    case SH7750_SCBRR1_A7:
666
        s->scbrr1 = mem_value;
667
        return;
668
    case SH7750_SCTDR1_A7:
669
        s->scssr1 &= ~SH7750_SCSSR1_TEND;
670
        s->sctdr1 = mem_value;
671
        return;
672
    case SH7750_SCSSR1_A7:
673
        serial1_change_scssr1(s, mem_value);
674
        return;
675
    default:
676
        error_access("byte write", addr);
677
        assert(0);
678
    }
679
}
680

    
681
static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr,
682
                              uint32_t mem_value)
683
{
684
    SH7750State *s = opaque;
685
    uint16_t temp;
686

    
687
    switch (addr) {
688
        /* SDRAM controller */
689
    case SH7750_SCBRR1_A7:
690
    case SH7750_SCBRR2_A7:
691
    case SH7750_BCR2_A7:
692
    case SH7750_BCR3_A7:
693
    case SH7750_RTCOR_A7:
694
    case SH7750_RTCNT_A7:
695
    case SH7750_RTCSR_A7:
696
        ignore_access("word write", addr);
697
        return;
698
        /* IO ports */
699
    case SH7750_PDTRA_A7:
700
        temp = porta_lines(s);
701
        s->pdtra = mem_value;
702
        porta_changed(s, temp);
703
        return;
704
    case SH7750_PDTRB_A7:
705
        temp = portb_lines(s);
706
        s->pdtrb = mem_value;
707
        portb_changed(s, temp);
708
        return;
709
    case SH7750_RFCR_A7:
710
        fprintf(stderr, "Write access to refresh count register\n");
711
        s->rfcr = mem_value;
712
        return;
713
    case SH7750_SCLSR2_A7:
714
        s->sclsr2 = mem_value;
715
        return;
716
    case SH7750_SCSCR2_A7:
717
        s->scscr2 = mem_value;
718
        scscr2_changed(s);
719
        return;
720
    case SH7750_SCFCR2_A7:
721
        s->scfcr2 = mem_value;
722
        return;
723
    case SH7750_SCSMR2_A7:
724
        s->scsmr2 = mem_value;
725
        return;
726
    case SH7750_TCR0_A7:
727
        s->tcr0 = mem_value;
728
        return;
729
    case SH7750_GPIOIC_A7:
730
        s->gpioic = mem_value;
731
        if (mem_value != 0) {
732
            fprintf(stderr, "I/O interrupts not implemented\n");
733
            assert(0);
734
        }
735
        return;
736
    default:
737
        error_access("word write", addr);
738
        assert(0);
739
    }
740
}
741

    
742
static void sh7750_mem_writel(void *opaque, target_phys_addr_t addr,
743
                              uint32_t mem_value)
744
{
745
    SH7750State *s = opaque;
746
    uint16_t temp;
747

    
748
    switch (addr) {
749
        /* SDRAM controller */
750
    case SH7750_BCR1_A7:
751
    case SH7750_BCR4_A7:
752
    case SH7750_WCR1_A7:
753
    case SH7750_WCR2_A7:
754
    case SH7750_WCR3_A7:
755
    case SH7750_MCR_A7:
756
        ignore_access("long write", addr);
757
        return;
758
        /* IO ports */
759
    case SH7750_PCTRA_A7:
760
        temp = porta_lines(s);
761
        s->pctra = mem_value;
762
        s->portdira = portdir(mem_value);
763
        s->portpullupa = portpullup(mem_value);
764
        porta_changed(s, temp);
765
        return;
766
    case SH7750_PCTRB_A7:
767
        temp = portb_lines(s);
768
        s->pctrb = mem_value;
769
        s->portdirb = portdir(mem_value);
770
        s->portpullupb = portpullup(mem_value);
771
        portb_changed(s, temp);
772
        return;
773
    case SH7750_TCNT0_A7:
774
        s->tcnt0 = mem_value & 0xf;
775
        return;
776
    case SH7750_MMUCR_A7:
777
        s->cpu->mmucr = mem_value;
778
        return;
779
    case SH7750_PTEH_A7:
780
        s->cpu->pteh = mem_value;
781
        return;
782
    case SH7750_PTEL_A7:
783
        s->cpu->ptel = mem_value;
784
        return;
785
    case SH7750_TTB_A7:
786
        s->cpu->ttb = mem_value;
787
        return;
788
    case SH7750_TEA_A7:
789
        s->cpu->tea = mem_value;
790
        return;
791
    case SH7750_TRA_A7:
792
        s->cpu->tra = mem_value & 0x000007ff;
793
        return;
794
    case SH7750_EXPEVT_A7:
795
        s->cpu->expevt = mem_value & 0x000007ff;
796
        return;
797
    case SH7750_INTEVT_A7:
798
        s->cpu->intevt = mem_value & 0x000007ff;
799
        return;
800
    case SH7750_CCR_A7:
801
        s->ccr = mem_value;
802
        return;
803
    default:
804
        error_access("long write", addr);
805
        assert(0);
806
    }
807
}
808

    
809
static CPUReadMemoryFunc *sh7750_mem_read[] = {
810
    sh7750_mem_readb,
811
    sh7750_mem_readw,
812
    sh7750_mem_readl
813
};
814

    
815
static CPUWriteMemoryFunc *sh7750_mem_write[] = {
816
    sh7750_mem_writeb,
817
    sh7750_mem_writew,
818
    sh7750_mem_writel
819
};
820

    
821
SH7750State *sh7750_init(CPUSH4State * cpu)
822
{
823
    SH7750State *s;
824
    int sh7750_io_memory;
825

    
826
    s = qemu_mallocz(sizeof(SH7750State));
827
    s->cpu = cpu;
828
    s->periph_freq = 60000000;        /* 60MHz */
829
    sh7750_io_memory = cpu_register_io_memory(0,
830
                                              sh7750_mem_read,
831
                                              sh7750_mem_write, s);
832
    cpu_register_physical_memory(0x1c000000, 0x04000000, sh7750_io_memory);
833
    init_timers(s);
834
    init_serial_ports(s);
835
    return s;
836
}