Statistics
| Branch: | Revision:

root / hw / sh7750.c @ 24c7b0e3

History | View | Annotate | Download (20.5 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_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
}
426

    
427
/**********************************************************************
428
 I/O ports
429
**********************************************************************/
430

    
431
int sh7750_register_io_device(SH7750State * s, sh7750_io_device * device)
432
{
433
    int i;
434

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

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

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

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

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

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

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

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

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

    
511
    if (r)
512
        gen_port_interrupts(s);
513
}
514

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

    
520
    currentb = portb_lines(s);
521
    if (currentb == prev)
522
        return;
523
    changes = currentb ^ prev;
524

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

    
535
    if (r)
536
        gen_port_interrupts(s);
537
}
538

    
539
/**********************************************************************
540
 Memory
541
**********************************************************************/
542

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

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

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

    
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;
568
    default:
569
        error_access("byte read", addr);
570
        assert(0);
571
    }
572
}
573

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

    
579
    switch (addr) {
580
    case SH7750_RFCR_A7:
581
        fprintf(stderr,
582
                "Read access to refresh count register, incrementing\n");
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;
593
    case SH7750_PDTRA_A7:
594
        return porta_lines(s);
595
    case SH7750_PDTRB_A7:
596
        return portb_lines(s);
597
    default:
598
        error_access("word read", addr);
599
        assert(0);
600
    }
601
}
602

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

    
607
    switch (addr) {
608
    case SH7750_MMUCR_A7:
609
        return s->cpu->mmucr;
610
    case SH7750_PTEH_A7:
611
        return s->cpu->pteh;
612
    case SH7750_PTEL_A7:
613
        return s->cpu->ptel;
614
    case SH7750_TTB_A7:
615
        return s->cpu->ttb;
616
    case SH7750_TEA_A7:
617
        return s->cpu->tea;
618
    case SH7750_TRA_A7:
619
        return s->cpu->tra;
620
    case SH7750_EXPEVT_A7:
621
        return s->cpu->expevt;
622
    case SH7750_INTEVT_A7:
623
        return s->cpu->intevt;
624
    case SH7750_CCR_A7:
625
        return s->ccr;
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 */
632
    default:
633
        error_access("long read", addr);
634
        assert(0);
635
    }
636
}
637

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

    
643
    switch (addr) {
644
        /* PRECHARGE ? XXXXX */
645
    case SH7750_PRECHARGE0_A7:
646
    case SH7750_PRECHARGE1_A7:
647
        ignore_access("byte write", addr);
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;
673
    default:
674
        error_access("byte write", addr);
675
        assert(0);
676
    }
677
}
678

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

    
685
    switch (addr) {
686
        /* SDRAM controller */
687
    case SH7750_SCBRR1_A7:
688
    case SH7750_SCBRR2_A7:
689
    case SH7750_BCR2_A7:
690
    case SH7750_BCR3_A7:
691
    case SH7750_RTCOR_A7:
692
    case SH7750_RTCNT_A7:
693
    case SH7750_RTCSR_A7:
694
        ignore_access("word write", addr);
695
        return;
696
        /* IO ports */
697
    case SH7750_PDTRA_A7:
698
        temp = porta_lines(s);
699
        s->pdtra = mem_value;
700
        porta_changed(s, temp);
701
        return;
702
    case SH7750_PDTRB_A7:
703
        temp = portb_lines(s);
704
        s->pdtrb = mem_value;
705
        portb_changed(s, temp);
706
        return;
707
    case SH7750_RFCR_A7:
708
        fprintf(stderr, "Write access to refresh count register\n");
709
        s->rfcr = mem_value;
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;
727
    case SH7750_GPIOIC_A7:
728
        s->gpioic = mem_value;
729
        if (mem_value != 0) {
730
            fprintf(stderr, "I/O interrupts not implemented\n");
731
            assert(0);
732
        }
733
        return;
734
    default:
735
        error_access("word write", addr);
736
        assert(0);
737
    }
738
}
739

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

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

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

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

    
819
SH7750State *sh7750_init(CPUSH4State * cpu)
820
{
821
    SH7750State *s;
822
    int sh7750_io_memory;
823

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