source: trunk/packages/xen-3.1/xen-3.1/tools/ioemu/hw/sh7750.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 20.6 KB
Line 
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
30typedef 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
39typedef 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
101static 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
134static 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
144static 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
162static 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
173static int serial1_can_receive(void *opaque)
174{
175    SH7750State *s = opaque;
176
177    return s->scscr1 & SH7750_SCSCR_RE;
178}
179
180static 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
191static 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
201static void serial1_event(void *opaque, int event)
202{
203    assert(0);
204}
205
206static 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
222static 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
248static 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
275static 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
289static 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
311static 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
320static 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
338static 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
351static 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
360static void serial2_event(void *opaque, int event)
361{
362    /* XXXXX */
363    assert(0);
364}
365
366static 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
393static 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
404static 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
423static 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
433int 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
446static 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
458static 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
469static 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
476static 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
483static void gen_port_interrupts(SH7750State * s)
484{
485    /* XXXXX interrupts not generated */
486}
487
488static 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
517static 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
545static 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
551static 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
557static 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
576static 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
605static 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
640static 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
681static 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
742static 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
809static CPUReadMemoryFunc *sh7750_mem_read[] = {
810    sh7750_mem_readb,
811    sh7750_mem_readw,
812    sh7750_mem_readl
813};
814
815static CPUWriteMemoryFunc *sh7750_mem_write[] = {
816    sh7750_mem_writeb,
817    sh7750_mem_writew,
818    sh7750_mem_writel
819};
820
821SH7750State *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}
Note: See TracBrowser for help on using the repository browser.