Statistics
| Branch: | Revision:

root / hw / sh7750.c @ 5fafdf24

History | View | Annotate | Download (20.5 kB)

1 27c7ca7e bellard
/*
2 27c7ca7e bellard
 * SH7750 device
3 5fafdf24 ths
 *
4 27c7ca7e bellard
 * Copyright (c) 2005 Samuel Tardieu
5 5fafdf24 ths
 *
6 27c7ca7e bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 27c7ca7e bellard
 * of this software and associated documentation files (the "Software"), to deal
8 27c7ca7e bellard
 * in the Software without restriction, including without limitation the rights
9 27c7ca7e bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 27c7ca7e bellard
 * copies of the Software, and to permit persons to whom the Software is
11 27c7ca7e bellard
 * furnished to do so, subject to the following conditions:
12 27c7ca7e bellard
 *
13 27c7ca7e bellard
 * The above copyright notice and this permission notice shall be included in
14 27c7ca7e bellard
 * all copies or substantial portions of the Software.
15 27c7ca7e bellard
 *
16 27c7ca7e bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 27c7ca7e bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 27c7ca7e bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 27c7ca7e bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 27c7ca7e bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 27c7ca7e bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 27c7ca7e bellard
 * THE SOFTWARE.
23 27c7ca7e bellard
 */
24 27c7ca7e bellard
#include <stdio.h>
25 27c7ca7e bellard
#include <assert.h>
26 27c7ca7e bellard
#include "vl.h"
27 27c7ca7e bellard
#include "sh7750_regs.h"
28 27c7ca7e bellard
#include "sh7750_regnames.h"
29 27c7ca7e bellard
30 27c7ca7e bellard
typedef struct {
31 27c7ca7e bellard
    uint8_t data[16];
32 27c7ca7e bellard
    uint8_t length;                /* Number of characters in the FIFO */
33 27c7ca7e bellard
    uint8_t write_idx;                /* Index of first character to write */
34 27c7ca7e bellard
    uint8_t read_idx;                /* Index of first character to read */
35 27c7ca7e bellard
} fifo;
36 27c7ca7e bellard
37 27c7ca7e bellard
#define NB_DEVICES 4
38 27c7ca7e bellard
39 27c7ca7e bellard
typedef struct SH7750State {
40 27c7ca7e bellard
    /* CPU */
41 27c7ca7e bellard
    CPUSH4State *cpu;
42 27c7ca7e bellard
    /* Peripheral frequency in Hz */
43 27c7ca7e bellard
    uint32_t periph_freq;
44 27c7ca7e bellard
    /* SDRAM controller */
45 27c7ca7e bellard
    uint16_t rfcr;
46 27c7ca7e bellard
    /* First serial port */
47 27c7ca7e bellard
    CharDriverState *serial1;
48 27c7ca7e bellard
    uint8_t scscr1;
49 27c7ca7e bellard
    uint8_t scsmr1;
50 27c7ca7e bellard
    uint8_t scbrr1;
51 27c7ca7e bellard
    uint8_t scssr1;
52 27c7ca7e bellard
    uint8_t scssr1_read;
53 27c7ca7e bellard
    uint8_t sctsr1;
54 27c7ca7e bellard
    uint8_t sctsr1_loaded;
55 27c7ca7e bellard
    uint8_t sctdr1;
56 27c7ca7e bellard
    uint8_t scrdr1;
57 27c7ca7e bellard
    /* Second serial port */
58 27c7ca7e bellard
    CharDriverState *serial2;
59 27c7ca7e bellard
    uint16_t sclsr2;
60 27c7ca7e bellard
    uint16_t scscr2;
61 27c7ca7e bellard
    uint16_t scfcr2;
62 27c7ca7e bellard
    uint16_t scfsr2;
63 27c7ca7e bellard
    uint16_t scsmr2;
64 27c7ca7e bellard
    uint8_t scbrr2;
65 27c7ca7e bellard
    fifo serial2_receive_fifo;
66 27c7ca7e bellard
    fifo serial2_transmit_fifo;
67 27c7ca7e bellard
    /* Timers */
68 27c7ca7e bellard
    uint8_t tstr;
69 27c7ca7e bellard
    /* Timer 0 */
70 27c7ca7e bellard
    QEMUTimer *timer0;
71 27c7ca7e bellard
    uint16_t tcr0;
72 27c7ca7e bellard
    uint32_t tcor0;
73 27c7ca7e bellard
    uint32_t tcnt0;
74 27c7ca7e bellard
    /* IO ports */
75 27c7ca7e bellard
    uint16_t gpioic;
76 27c7ca7e bellard
    uint32_t pctra;
77 27c7ca7e bellard
    uint32_t pctrb;
78 27c7ca7e bellard
    uint16_t portdira;                /* Cached */
79 27c7ca7e bellard
    uint16_t portpullupa;        /* Cached */
80 27c7ca7e bellard
    uint16_t portdirb;                /* Cached */
81 27c7ca7e bellard
    uint16_t portpullupb;        /* Cached */
82 27c7ca7e bellard
    uint16_t pdtra;
83 27c7ca7e bellard
    uint16_t pdtrb;
84 27c7ca7e bellard
    uint16_t periph_pdtra;        /* Imposed by the peripherals */
85 27c7ca7e bellard
    uint16_t periph_portdira;        /* Direction seen from the peripherals */
86 27c7ca7e bellard
    uint16_t periph_pdtrb;        /* Imposed by the peripherals */
87 27c7ca7e bellard
    uint16_t periph_portdirb;        /* Direction seen from the peripherals */
88 27c7ca7e bellard
    sh7750_io_device *devices[NB_DEVICES];        /* External peripherals */
89 27c7ca7e bellard
    /* Cache */
90 27c7ca7e bellard
    uint32_t ccr;
91 27c7ca7e bellard
} SH7750State;
92 27c7ca7e bellard
93 27c7ca7e bellard
/**********************************************************************
94 27c7ca7e bellard
 Timers
95 27c7ca7e bellard
**********************************************************************/
96 27c7ca7e bellard
97 27c7ca7e bellard
/* XXXXX At this time, timer0 works in underflow only mode, that is
98 27c7ca7e bellard
   the value of tcnt0 is read at alarm computation time and cannot
99 27c7ca7e bellard
   be read back by the guest OS */
100 27c7ca7e bellard
101 27c7ca7e bellard
static void start_timer0(SH7750State * s)
102 27c7ca7e bellard
{
103 27c7ca7e bellard
    uint64_t now, next, prescaler;
104 27c7ca7e bellard
105 27c7ca7e bellard
    if ((s->tcr0 & 6) == 6) {
106 27c7ca7e bellard
        fprintf(stderr, "rtc clock for timer 0 not supported\n");
107 27c7ca7e bellard
        assert(0);
108 27c7ca7e bellard
    }
109 27c7ca7e bellard
110 27c7ca7e bellard
    if ((s->tcr0 & 7) == 5) {
111 27c7ca7e bellard
        fprintf(stderr, "timer 0 configuration not supported\n");
112 27c7ca7e bellard
        assert(0);
113 27c7ca7e bellard
    }
114 27c7ca7e bellard
115 27c7ca7e bellard
    if ((s->tcr0 & 4) == 4)
116 27c7ca7e bellard
        prescaler = 1024;
117 27c7ca7e bellard
    else
118 27c7ca7e bellard
        prescaler = 4 << (s->tcr0 & 3);
119 27c7ca7e bellard
120 27c7ca7e bellard
    now = qemu_get_clock(vm_clock);
121 27c7ca7e bellard
    /* XXXXX */
122 27c7ca7e bellard
    next =
123 27c7ca7e bellard
        now + muldiv64(prescaler * s->tcnt0, ticks_per_sec,
124 27c7ca7e bellard
                       s->periph_freq);
125 27c7ca7e bellard
    if (next == now)
126 27c7ca7e bellard
        next = now + 1;
127 26a76461 bellard
    fprintf(stderr, "now=%016" PRIx64 ", next=%016" PRIx64 "\n", now, next);
128 27c7ca7e bellard
    fprintf(stderr, "timer will underflow in %f seconds\n",
129 27c7ca7e bellard
            (float) (next - now) / (float) ticks_per_sec);
130 27c7ca7e bellard
131 27c7ca7e bellard
    qemu_mod_timer(s->timer0, next);
132 27c7ca7e bellard
}
133 27c7ca7e bellard
134 27c7ca7e bellard
static void timer_start_changed(SH7750State * s)
135 27c7ca7e bellard
{
136 27c7ca7e bellard
    if (s->tstr & SH7750_TSTR_STR0) {
137 27c7ca7e bellard
        start_timer0(s);
138 27c7ca7e bellard
    } else {
139 27c7ca7e bellard
        fprintf(stderr, "timer 0 is stopped\n");
140 27c7ca7e bellard
        qemu_del_timer(s->timer0);
141 27c7ca7e bellard
    }
142 27c7ca7e bellard
}
143 27c7ca7e bellard
144 27c7ca7e bellard
static void timer0_cb(void *opaque)
145 27c7ca7e bellard
{
146 27c7ca7e bellard
    SH7750State *s = opaque;
147 27c7ca7e bellard
148 27c7ca7e bellard
    s->tcnt0 = (uint32_t) 0;        /* XXXXX */
149 27c7ca7e bellard
    if (--s->tcnt0 == (uint32_t) - 1) {
150 27c7ca7e bellard
        fprintf(stderr, "timer 0 underflow\n");
151 27c7ca7e bellard
        s->tcnt0 = s->tcor0;
152 27c7ca7e bellard
        s->tcr0 |= SH7750_TCR_UNF;
153 27c7ca7e bellard
        if (s->tcr0 & SH7750_TCR_UNIE) {
154 27c7ca7e bellard
            fprintf(stderr,
155 27c7ca7e bellard
                    "interrupt generation for timer 0 not supported\n");
156 27c7ca7e bellard
            assert(0);
157 27c7ca7e bellard
        }
158 27c7ca7e bellard
    }
159 27c7ca7e bellard
    start_timer0(s);
160 27c7ca7e bellard
}
161 27c7ca7e bellard
162 27c7ca7e bellard
static void init_timers(SH7750State * s)
163 27c7ca7e bellard
{
164 27c7ca7e bellard
    s->tcor0 = 0xffffffff;
165 27c7ca7e bellard
    s->tcnt0 = 0xffffffff;
166 27c7ca7e bellard
    s->timer0 = qemu_new_timer(vm_clock, &timer0_cb, s);
167 27c7ca7e bellard
}
168 27c7ca7e bellard
169 27c7ca7e bellard
/**********************************************************************
170 27c7ca7e bellard
 First serial port
171 27c7ca7e bellard
**********************************************************************/
172 27c7ca7e bellard
173 27c7ca7e bellard
static int serial1_can_receive(void *opaque)
174 27c7ca7e bellard
{
175 27c7ca7e bellard
    SH7750State *s = opaque;
176 27c7ca7e bellard
177 27c7ca7e bellard
    return s->scscr1 & SH7750_SCSCR_RE;
178 27c7ca7e bellard
}
179 27c7ca7e bellard
180 27c7ca7e bellard
static void serial1_receive_char(SH7750State * s, uint8_t c)
181 27c7ca7e bellard
{
182 27c7ca7e bellard
    if (s->scssr1 & SH7750_SCSSR1_RDRF) {
183 27c7ca7e bellard
        s->scssr1 |= SH7750_SCSSR1_ORER;
184 27c7ca7e bellard
        return;
185 27c7ca7e bellard
    }
186 27c7ca7e bellard
187 27c7ca7e bellard
    s->scrdr1 = c;
188 27c7ca7e bellard
    s->scssr1 |= SH7750_SCSSR1_RDRF;
189 27c7ca7e bellard
}
190 27c7ca7e bellard
191 27c7ca7e bellard
static void serial1_receive(void *opaque, const uint8_t * buf, int size)
192 27c7ca7e bellard
{
193 27c7ca7e bellard
    SH7750State *s = opaque;
194 27c7ca7e bellard
    int i;
195 27c7ca7e bellard
196 27c7ca7e bellard
    for (i = 0; i < size; i++) {
197 27c7ca7e bellard
        serial1_receive_char(s, buf[i]);
198 27c7ca7e bellard
    }
199 27c7ca7e bellard
}
200 27c7ca7e bellard
201 27c7ca7e bellard
static void serial1_event(void *opaque, int event)
202 27c7ca7e bellard
{
203 27c7ca7e bellard
    assert(0);
204 27c7ca7e bellard
}
205 27c7ca7e bellard
206 27c7ca7e bellard
static void serial1_maybe_send(SH7750State * s)
207 27c7ca7e bellard
{
208 27c7ca7e bellard
    uint8_t c;
209 27c7ca7e bellard
210 27c7ca7e bellard
    if (s->scssr1 & SH7750_SCSSR1_TDRE)
211 27c7ca7e bellard
        return;
212 27c7ca7e bellard
    c = s->sctdr1;
213 27c7ca7e bellard
    s->scssr1 |= SH7750_SCSSR1_TDRE | SH7750_SCSSR1_TEND;
214 27c7ca7e bellard
    if (s->scscr1 & SH7750_SCSCR_TIE) {
215 27c7ca7e bellard
        fprintf(stderr, "interrupts for serial port 1 not implemented\n");
216 27c7ca7e bellard
        assert(0);
217 27c7ca7e bellard
    }
218 27c7ca7e bellard
    /* XXXXX Check for errors in write */
219 27c7ca7e bellard
    qemu_chr_write(s->serial1, &c, 1);
220 27c7ca7e bellard
}
221 27c7ca7e bellard
222 27c7ca7e bellard
static void serial1_change_scssr1(SH7750State * s, uint8_t mem_value)
223 27c7ca7e bellard
{
224 27c7ca7e bellard
    uint8_t new_flags;
225 27c7ca7e bellard
226 27c7ca7e bellard
    /* If transmit disable, TDRE and TEND stays up */
227 27c7ca7e bellard
    if ((s->scscr1 & SH7750_SCSCR_TE) == 0) {
228 27c7ca7e bellard
        mem_value |= SH7750_SCSSR1_TDRE | SH7750_SCSSR1_TEND;
229 27c7ca7e bellard
    }
230 27c7ca7e bellard
231 27c7ca7e bellard
    /* Only clear bits which have been read before and do not set any bit
232 27c7ca7e bellard
       in the flags */
233 27c7ca7e bellard
    new_flags = s->scssr1 & ~s->scssr1_read;        /* Preserve unread flags */
234 27c7ca7e bellard
    new_flags &= mem_value | ~s->scssr1_read;        /* Clear read flags */
235 27c7ca7e bellard
236 27c7ca7e bellard
    s->scssr1 = (new_flags & 0xf8) | (mem_value & 1);
237 27c7ca7e bellard
    s->scssr1_read &= mem_value;
238 27c7ca7e bellard
239 27c7ca7e bellard
    /* If TDRE has been cleared, TEND will also be cleared */
240 27c7ca7e bellard
    if ((s->scssr1 & SH7750_SCSSR1_TDRE) == 0) {
241 27c7ca7e bellard
        s->scssr1 &= ~SH7750_SCSSR1_TEND;
242 27c7ca7e bellard
    }
243 27c7ca7e bellard
244 27c7ca7e bellard
    /* Check for transmission to start */
245 27c7ca7e bellard
    serial1_maybe_send(s);
246 27c7ca7e bellard
}
247 27c7ca7e bellard
248 27c7ca7e bellard
static void serial1_update_parameters(SH7750State * s)
249 27c7ca7e bellard
{
250 27c7ca7e bellard
    QEMUSerialSetParams ssp;
251 27c7ca7e bellard
252 27c7ca7e bellard
    if (s->scsmr1 & SH7750_SCSMR_CHR_7)
253 27c7ca7e bellard
        ssp.data_bits = 7;
254 27c7ca7e bellard
    else
255 27c7ca7e bellard
        ssp.data_bits = 8;
256 27c7ca7e bellard
    if (s->scsmr1 & SH7750_SCSMR_PE) {
257 27c7ca7e bellard
        if (s->scsmr1 & SH7750_SCSMR_PM_ODD)
258 27c7ca7e bellard
            ssp.parity = 'O';
259 27c7ca7e bellard
        else
260 27c7ca7e bellard
            ssp.parity = 'E';
261 27c7ca7e bellard
    } else
262 27c7ca7e bellard
        ssp.parity = 'N';
263 27c7ca7e bellard
    if (s->scsmr1 & SH7750_SCSMR_STOP_2)
264 27c7ca7e bellard
        ssp.stop_bits = 2;
265 27c7ca7e bellard
    else
266 27c7ca7e bellard
        ssp.stop_bits = 1;
267 27c7ca7e bellard
    fprintf(stderr, "SCSMR1=%04x SCBRR1=%02x\n", s->scsmr1, s->scbrr1);
268 27c7ca7e bellard
    ssp.speed = s->periph_freq /
269 27c7ca7e bellard
        (32 * s->scbrr1 * (1 << (2 * (s->scsmr1 & 3)))) - 1;
270 27c7ca7e bellard
    fprintf(stderr, "data bits=%d, stop bits=%d, parity=%c, speed=%d\n",
271 27c7ca7e bellard
            ssp.data_bits, ssp.stop_bits, ssp.parity, ssp.speed);
272 27c7ca7e bellard
    qemu_chr_ioctl(s->serial1, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
273 27c7ca7e bellard
}
274 27c7ca7e bellard
275 27c7ca7e bellard
static void scscr1_changed(SH7750State * s)
276 27c7ca7e bellard
{
277 27c7ca7e bellard
    if (s->scscr1 & (SH7750_SCSCR_TE | SH7750_SCSCR_RE)) {
278 27c7ca7e bellard
        if (!s->serial1) {
279 27c7ca7e bellard
            fprintf(stderr, "serial port 1 not bound to anything\n");
280 27c7ca7e bellard
            assert(0);
281 27c7ca7e bellard
        }
282 27c7ca7e bellard
        serial1_update_parameters(s);
283 27c7ca7e bellard
    }
284 27c7ca7e bellard
    if ((s->scscr1 & SH7750_SCSCR_RE) == 0) {
285 27c7ca7e bellard
        s->scssr1 |= SH7750_SCSSR1_TDRE;
286 27c7ca7e bellard
    }
287 27c7ca7e bellard
}
288 27c7ca7e bellard
289 27c7ca7e bellard
static void init_serial1(SH7750State * s, int serial_nb)
290 27c7ca7e bellard
{
291 27c7ca7e bellard
    CharDriverState *chr;
292 27c7ca7e bellard
293 27c7ca7e bellard
    s->scssr1 = 0x84;
294 27c7ca7e bellard
    chr = serial_hds[serial_nb];
295 27c7ca7e bellard
    if (!chr) {
296 27c7ca7e bellard
        fprintf(stderr,
297 27c7ca7e bellard
                "no serial port associated to SH7750 first serial port\n");
298 27c7ca7e bellard
        return;
299 27c7ca7e bellard
    }
300 27c7ca7e bellard
301 27c7ca7e bellard
    s->serial1 = chr;
302 e5b0bc44 pbrook
    qemu_chr_add_handlers(chr, serial1_can_receive,
303 e5b0bc44 pbrook
                          serial1_receive, serial1_event, s);
304 27c7ca7e bellard
}
305 27c7ca7e bellard
306 27c7ca7e bellard
/**********************************************************************
307 27c7ca7e bellard
 Second serial port
308 27c7ca7e bellard
**********************************************************************/
309 27c7ca7e bellard
310 27c7ca7e bellard
static int serial2_can_receive(void *opaque)
311 27c7ca7e bellard
{
312 27c7ca7e bellard
    SH7750State *s = opaque;
313 27c7ca7e bellard
    static uint8_t max_fifo_size[] = { 15, 1, 4, 6, 8, 10, 12, 14 };
314 27c7ca7e bellard
315 27c7ca7e bellard
    return s->serial2_receive_fifo.length <
316 27c7ca7e bellard
        max_fifo_size[(s->scfcr2 >> 9) & 7];
317 27c7ca7e bellard
}
318 27c7ca7e bellard
319 27c7ca7e bellard
static void serial2_adjust_receive_flags(SH7750State * s)
320 27c7ca7e bellard
{
321 27c7ca7e bellard
    static uint8_t max_fifo_size[] = { 1, 4, 8, 14 };
322 27c7ca7e bellard
323 27c7ca7e bellard
    /* XXXXX Add interrupt generation */
324 27c7ca7e bellard
    if (s->serial2_receive_fifo.length >=
325 27c7ca7e bellard
        max_fifo_size[(s->scfcr2 >> 7) & 3]) {
326 27c7ca7e bellard
        s->scfsr2 |= SH7750_SCFSR2_RDF;
327 27c7ca7e bellard
        s->scfsr2 &= ~SH7750_SCFSR2_DR;
328 27c7ca7e bellard
    } else {
329 27c7ca7e bellard
        s->scfsr2 &= ~SH7750_SCFSR2_RDF;
330 27c7ca7e bellard
        if (s->serial2_receive_fifo.length > 0)
331 27c7ca7e bellard
            s->scfsr2 |= SH7750_SCFSR2_DR;
332 27c7ca7e bellard
        else
333 27c7ca7e bellard
            s->scfsr2 &= ~SH7750_SCFSR2_DR;
334 27c7ca7e bellard
    }
335 27c7ca7e bellard
}
336 27c7ca7e bellard
337 27c7ca7e bellard
static void serial2_append_char(SH7750State * s, uint8_t c)
338 27c7ca7e bellard
{
339 27c7ca7e bellard
    if (s->serial2_receive_fifo.length == 16) {
340 27c7ca7e bellard
        /* Overflow */
341 27c7ca7e bellard
        s->sclsr2 |= SH7750_SCLSR2_ORER;
342 27c7ca7e bellard
        return;
343 27c7ca7e bellard
    }
344 27c7ca7e bellard
345 27c7ca7e bellard
    s->serial2_receive_fifo.data[s->serial2_receive_fifo.write_idx++] = c;
346 27c7ca7e bellard
    s->serial2_receive_fifo.length++;
347 27c7ca7e bellard
    serial2_adjust_receive_flags(s);
348 27c7ca7e bellard
}
349 27c7ca7e bellard
350 27c7ca7e bellard
static void serial2_receive(void *opaque, const uint8_t * buf, int size)
351 27c7ca7e bellard
{
352 27c7ca7e bellard
    SH7750State *s = opaque;
353 27c7ca7e bellard
    int i;
354 27c7ca7e bellard
355 27c7ca7e bellard
    for (i = 0; i < size; i++)
356 27c7ca7e bellard
        serial2_append_char(s, buf[i]);
357 27c7ca7e bellard
}
358 27c7ca7e bellard
359 27c7ca7e bellard
static void serial2_event(void *opaque, int event)
360 27c7ca7e bellard
{
361 27c7ca7e bellard
    /* XXXXX */
362 27c7ca7e bellard
    assert(0);
363 27c7ca7e bellard
}
364 27c7ca7e bellard
365 27c7ca7e bellard
static void serial2_update_parameters(SH7750State * s)
366 27c7ca7e bellard
{
367 27c7ca7e bellard
    QEMUSerialSetParams ssp;
368 27c7ca7e bellard
369 27c7ca7e bellard
    if (s->scsmr2 & SH7750_SCSMR_CHR_7)
370 27c7ca7e bellard
        ssp.data_bits = 7;
371 27c7ca7e bellard
    else
372 27c7ca7e bellard
        ssp.data_bits = 8;
373 27c7ca7e bellard
    if (s->scsmr2 & SH7750_SCSMR_PE) {
374 27c7ca7e bellard
        if (s->scsmr2 & SH7750_SCSMR_PM_ODD)
375 27c7ca7e bellard
            ssp.parity = 'O';
376 27c7ca7e bellard
        else
377 27c7ca7e bellard
            ssp.parity = 'E';
378 27c7ca7e bellard
    } else
379 27c7ca7e bellard
        ssp.parity = 'N';
380 27c7ca7e bellard
    if (s->scsmr2 & SH7750_SCSMR_STOP_2)
381 27c7ca7e bellard
        ssp.stop_bits = 2;
382 27c7ca7e bellard
    else
383 27c7ca7e bellard
        ssp.stop_bits = 1;
384 27c7ca7e bellard
    fprintf(stderr, "SCSMR2=%04x SCBRR2=%02x\n", s->scsmr2, s->scbrr2);
385 27c7ca7e bellard
    ssp.speed = s->periph_freq /
386 27c7ca7e bellard
        (32 * s->scbrr2 * (1 << (2 * (s->scsmr2 & 3)))) - 1;
387 27c7ca7e bellard
    fprintf(stderr, "data bits=%d, stop bits=%d, parity=%c, speed=%d\n",
388 27c7ca7e bellard
            ssp.data_bits, ssp.stop_bits, ssp.parity, ssp.speed);
389 27c7ca7e bellard
    qemu_chr_ioctl(s->serial2, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
390 27c7ca7e bellard
}
391 27c7ca7e bellard
392 27c7ca7e bellard
static void scscr2_changed(SH7750State * s)
393 27c7ca7e bellard
{
394 27c7ca7e bellard
    if (s->scscr2 & (SH7750_SCSCR_TE | SH7750_SCSCR_RE)) {
395 27c7ca7e bellard
        if (!s->serial2) {
396 27c7ca7e bellard
            fprintf(stderr, "serial port 2 not bound to anything\n");
397 27c7ca7e bellard
            assert(0);
398 27c7ca7e bellard
        }
399 27c7ca7e bellard
        serial2_update_parameters(s);
400 27c7ca7e bellard
    }
401 27c7ca7e bellard
}
402 27c7ca7e bellard
403 27c7ca7e bellard
static void init_serial2(SH7750State * s, int serial_nb)
404 27c7ca7e bellard
{
405 27c7ca7e bellard
    CharDriverState *chr;
406 27c7ca7e bellard
407 27c7ca7e bellard
    s->scfsr2 = 0x0060;
408 27c7ca7e bellard
409 27c7ca7e bellard
    chr = serial_hds[serial_nb];
410 27c7ca7e bellard
    if (!chr) {
411 27c7ca7e bellard
        fprintf(stderr,
412 27c7ca7e bellard
                "no serial port associated to SH7750 second serial port\n");
413 27c7ca7e bellard
        return;
414 27c7ca7e bellard
    }
415 27c7ca7e bellard
416 27c7ca7e bellard
    s->serial2 = chr;
417 e5b0bc44 pbrook
    qemu_chr_add_handlers(chr, serial2_can_receive,
418 e5b0bc44 pbrook
                          serial2_receive, serial1_event, s);
419 27c7ca7e bellard
}
420 27c7ca7e bellard
421 27c7ca7e bellard
static void init_serial_ports(SH7750State * s)
422 27c7ca7e bellard
{
423 27c7ca7e bellard
    init_serial1(s, 0);
424 27c7ca7e bellard
    init_serial2(s, 1);
425 27c7ca7e bellard
}
426 27c7ca7e bellard
427 27c7ca7e bellard
/**********************************************************************
428 27c7ca7e bellard
 I/O ports
429 27c7ca7e bellard
**********************************************************************/
430 27c7ca7e bellard
431 27c7ca7e bellard
int sh7750_register_io_device(SH7750State * s, sh7750_io_device * device)
432 27c7ca7e bellard
{
433 27c7ca7e bellard
    int i;
434 27c7ca7e bellard
435 27c7ca7e bellard
    for (i = 0; i < NB_DEVICES; i++) {
436 27c7ca7e bellard
        if (s->devices[i] == NULL) {
437 27c7ca7e bellard
            s->devices[i] = device;
438 27c7ca7e bellard
            return 0;
439 27c7ca7e bellard
        }
440 27c7ca7e bellard
    }
441 27c7ca7e bellard
    return -1;
442 27c7ca7e bellard
}
443 27c7ca7e bellard
444 27c7ca7e bellard
static uint16_t portdir(uint32_t v)
445 27c7ca7e bellard
{
446 27c7ca7e bellard
#define EVENPORTMASK(n) ((v & (1<<((n)<<1))) >> (n))
447 27c7ca7e bellard
    return
448 27c7ca7e bellard
        EVENPORTMASK(15) | EVENPORTMASK(14) | EVENPORTMASK(13) |
449 27c7ca7e bellard
        EVENPORTMASK(12) | EVENPORTMASK(11) | EVENPORTMASK(10) |
450 27c7ca7e bellard
        EVENPORTMASK(9) | EVENPORTMASK(8) | EVENPORTMASK(7) |
451 27c7ca7e bellard
        EVENPORTMASK(6) | EVENPORTMASK(5) | EVENPORTMASK(4) |
452 27c7ca7e bellard
        EVENPORTMASK(3) | EVENPORTMASK(2) | EVENPORTMASK(1) |
453 27c7ca7e bellard
        EVENPORTMASK(0);
454 27c7ca7e bellard
}
455 27c7ca7e bellard
456 27c7ca7e bellard
static uint16_t portpullup(uint32_t v)
457 27c7ca7e bellard
{
458 27c7ca7e bellard
#define ODDPORTMASK(n) ((v & (1<<(((n)<<1)+1))) >> (n))
459 27c7ca7e bellard
    return
460 27c7ca7e bellard
        ODDPORTMASK(15) | ODDPORTMASK(14) | ODDPORTMASK(13) |
461 27c7ca7e bellard
        ODDPORTMASK(12) | ODDPORTMASK(11) | ODDPORTMASK(10) |
462 27c7ca7e bellard
        ODDPORTMASK(9) | ODDPORTMASK(8) | ODDPORTMASK(7) | ODDPORTMASK(6) |
463 27c7ca7e bellard
        ODDPORTMASK(5) | ODDPORTMASK(4) | ODDPORTMASK(3) | ODDPORTMASK(2) |
464 27c7ca7e bellard
        ODDPORTMASK(1) | ODDPORTMASK(0);
465 27c7ca7e bellard
}
466 27c7ca7e bellard
467 27c7ca7e bellard
static uint16_t porta_lines(SH7750State * s)
468 27c7ca7e bellard
{
469 27c7ca7e bellard
    return (s->portdira & s->pdtra) |        /* CPU */
470 27c7ca7e bellard
        (s->periph_portdira & s->periph_pdtra) |        /* Peripherals */
471 27c7ca7e bellard
        (~(s->portdira | s->periph_portdira) & s->portpullupa);        /* Pullups */
472 27c7ca7e bellard
}
473 27c7ca7e bellard
474 27c7ca7e bellard
static uint16_t portb_lines(SH7750State * s)
475 27c7ca7e bellard
{
476 27c7ca7e bellard
    return (s->portdirb & s->pdtrb) |        /* CPU */
477 27c7ca7e bellard
        (s->periph_portdirb & s->periph_pdtrb) |        /* Peripherals */
478 27c7ca7e bellard
        (~(s->portdirb | s->periph_portdirb) & s->portpullupb);        /* Pullups */
479 27c7ca7e bellard
}
480 27c7ca7e bellard
481 27c7ca7e bellard
static void gen_port_interrupts(SH7750State * s)
482 27c7ca7e bellard
{
483 27c7ca7e bellard
    /* XXXXX interrupts not generated */
484 27c7ca7e bellard
}
485 27c7ca7e bellard
486 27c7ca7e bellard
static void porta_changed(SH7750State * s, uint16_t prev)
487 27c7ca7e bellard
{
488 27c7ca7e bellard
    uint16_t currenta, changes;
489 27c7ca7e bellard
    int i, r = 0;
490 27c7ca7e bellard
491 27c7ca7e bellard
#if 0
492 27c7ca7e bellard
    fprintf(stderr, "porta changed from 0x%04x to 0x%04x\n",
493 27c7ca7e bellard
            prev, porta_lines(s));
494 27c7ca7e bellard
    fprintf(stderr, "pdtra=0x%04x, pctra=0x%08x\n", s->pdtra, s->pctra);
495 27c7ca7e bellard
#endif
496 27c7ca7e bellard
    currenta = porta_lines(s);
497 27c7ca7e bellard
    if (currenta == prev)
498 27c7ca7e bellard
        return;
499 27c7ca7e bellard
    changes = currenta ^ prev;
500 27c7ca7e bellard
501 27c7ca7e bellard
    for (i = 0; i < NB_DEVICES; i++) {
502 27c7ca7e bellard
        if (s->devices[i] && (s->devices[i]->portamask_trigger & changes)) {
503 27c7ca7e bellard
            r |= s->devices[i]->port_change_cb(currenta, portb_lines(s),
504 27c7ca7e bellard
                                               &s->periph_pdtra,
505 27c7ca7e bellard
                                               &s->periph_portdira,
506 27c7ca7e bellard
                                               &s->periph_pdtrb,
507 27c7ca7e bellard
                                               &s->periph_portdirb);
508 27c7ca7e bellard
        }
509 27c7ca7e bellard
    }
510 27c7ca7e bellard
511 27c7ca7e bellard
    if (r)
512 27c7ca7e bellard
        gen_port_interrupts(s);
513 27c7ca7e bellard
}
514 27c7ca7e bellard
515 27c7ca7e bellard
static void portb_changed(SH7750State * s, uint16_t prev)
516 27c7ca7e bellard
{
517 27c7ca7e bellard
    uint16_t currentb, changes;
518 27c7ca7e bellard
    int i, r = 0;
519 27c7ca7e bellard
520 27c7ca7e bellard
    currentb = portb_lines(s);
521 27c7ca7e bellard
    if (currentb == prev)
522 27c7ca7e bellard
        return;
523 27c7ca7e bellard
    changes = currentb ^ prev;
524 27c7ca7e bellard
525 27c7ca7e bellard
    for (i = 0; i < NB_DEVICES; i++) {
526 27c7ca7e bellard
        if (s->devices[i] && (s->devices[i]->portbmask_trigger & changes)) {
527 27c7ca7e bellard
            r |= s->devices[i]->port_change_cb(portb_lines(s), currentb,
528 27c7ca7e bellard
                                               &s->periph_pdtra,
529 27c7ca7e bellard
                                               &s->periph_portdira,
530 27c7ca7e bellard
                                               &s->periph_pdtrb,
531 27c7ca7e bellard
                                               &s->periph_portdirb);
532 27c7ca7e bellard
        }
533 27c7ca7e bellard
    }
534 27c7ca7e bellard
535 27c7ca7e bellard
    if (r)
536 27c7ca7e bellard
        gen_port_interrupts(s);
537 27c7ca7e bellard
}
538 27c7ca7e bellard
539 27c7ca7e bellard
/**********************************************************************
540 27c7ca7e bellard
 Memory
541 27c7ca7e bellard
**********************************************************************/
542 27c7ca7e bellard
543 27c7ca7e bellard
static void error_access(const char *kind, target_phys_addr_t addr)
544 27c7ca7e bellard
{
545 27c7ca7e bellard
    fprintf(stderr, "%s to %s (0x%08x) not supported\n",
546 27c7ca7e bellard
            kind, regname(addr), addr);
547 27c7ca7e bellard
}
548 27c7ca7e bellard
549 27c7ca7e bellard
static void ignore_access(const char *kind, target_phys_addr_t addr)
550 27c7ca7e bellard
{
551 27c7ca7e bellard
    fprintf(stderr, "%s to %s (0x%08x) ignored\n",
552 27c7ca7e bellard
            kind, regname(addr), addr);
553 27c7ca7e bellard
}
554 27c7ca7e bellard
555 27c7ca7e bellard
static uint32_t sh7750_mem_readb(void *opaque, target_phys_addr_t addr)
556 27c7ca7e bellard
{
557 27c7ca7e bellard
    SH7750State *s = opaque;
558 27c7ca7e bellard
    uint8_t r;
559 27c7ca7e bellard
560 27c7ca7e bellard
    switch (addr) {
561 27c7ca7e bellard
    case SH7750_SCSSR1_A7:
562 27c7ca7e bellard
        r = s->scssr1;
563 27c7ca7e bellard
        s->scssr1_read |= r;
564 27c7ca7e bellard
        return s->scssr1;
565 27c7ca7e bellard
    case SH7750_SCRDR1_A7:
566 27c7ca7e bellard
        s->scssr1 &= ~SH7750_SCSSR1_RDRF;
567 27c7ca7e bellard
        return s->scrdr1;
568 27c7ca7e bellard
    default:
569 27c7ca7e bellard
        error_access("byte read", addr);
570 27c7ca7e bellard
        assert(0);
571 27c7ca7e bellard
    }
572 27c7ca7e bellard
}
573 27c7ca7e bellard
574 27c7ca7e bellard
static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr)
575 27c7ca7e bellard
{
576 27c7ca7e bellard
    SH7750State *s = opaque;
577 27c7ca7e bellard
    uint16_t r;
578 27c7ca7e bellard
579 27c7ca7e bellard
    switch (addr) {
580 27c7ca7e bellard
    case SH7750_RFCR_A7:
581 27c7ca7e bellard
        fprintf(stderr,
582 27c7ca7e bellard
                "Read access to refresh count register, incrementing\n");
583 27c7ca7e bellard
        return s->rfcr++;
584 27c7ca7e bellard
    case SH7750_TCR0_A7:
585 27c7ca7e bellard
        return s->tcr0;
586 27c7ca7e bellard
    case SH7750_SCLSR2_A7:
587 27c7ca7e bellard
        /* Read and clear overflow bit */
588 27c7ca7e bellard
        r = s->sclsr2;
589 27c7ca7e bellard
        s->sclsr2 = 0;
590 27c7ca7e bellard
        return r;
591 27c7ca7e bellard
    case SH7750_SCSFR2_A7:
592 27c7ca7e bellard
        return s->scfsr2;
593 27c7ca7e bellard
    case SH7750_PDTRA_A7:
594 27c7ca7e bellard
        return porta_lines(s);
595 27c7ca7e bellard
    case SH7750_PDTRB_A7:
596 27c7ca7e bellard
        return portb_lines(s);
597 27c7ca7e bellard
    default:
598 27c7ca7e bellard
        error_access("word read", addr);
599 27c7ca7e bellard
        assert(0);
600 27c7ca7e bellard
    }
601 27c7ca7e bellard
}
602 27c7ca7e bellard
603 27c7ca7e bellard
static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr)
604 27c7ca7e bellard
{
605 27c7ca7e bellard
    SH7750State *s = opaque;
606 27c7ca7e bellard
607 27c7ca7e bellard
    switch (addr) {
608 27c7ca7e bellard
    case SH7750_MMUCR_A7:
609 27c7ca7e bellard
        return s->cpu->mmucr;
610 27c7ca7e bellard
    case SH7750_PTEH_A7:
611 27c7ca7e bellard
        return s->cpu->pteh;
612 27c7ca7e bellard
    case SH7750_PTEL_A7:
613 27c7ca7e bellard
        return s->cpu->ptel;
614 27c7ca7e bellard
    case SH7750_TTB_A7:
615 27c7ca7e bellard
        return s->cpu->ttb;
616 27c7ca7e bellard
    case SH7750_TEA_A7:
617 27c7ca7e bellard
        return s->cpu->tea;
618 27c7ca7e bellard
    case SH7750_TRA_A7:
619 27c7ca7e bellard
        return s->cpu->tra;
620 27c7ca7e bellard
    case SH7750_EXPEVT_A7:
621 27c7ca7e bellard
        return s->cpu->expevt;
622 27c7ca7e bellard
    case SH7750_INTEVT_A7:
623 27c7ca7e bellard
        return s->cpu->intevt;
624 27c7ca7e bellard
    case SH7750_CCR_A7:
625 27c7ca7e bellard
        return s->ccr;
626 27c7ca7e bellard
    case 0x1f000030:                /* Processor version PVR */
627 27c7ca7e bellard
        return 0x00050000;        /* SH7750R */
628 27c7ca7e bellard
    case 0x1f000040:                /* Processor version CVR */
629 27c7ca7e bellard
        return 0x00110000;        /* Minimum caches */
630 27c7ca7e bellard
    case 0x1f000044:                /* Processor version PRR */
631 27c7ca7e bellard
        return 0x00000100;        /* SH7750R */
632 27c7ca7e bellard
    default:
633 27c7ca7e bellard
        error_access("long read", addr);
634 27c7ca7e bellard
        assert(0);
635 27c7ca7e bellard
    }
636 27c7ca7e bellard
}
637 27c7ca7e bellard
638 27c7ca7e bellard
static void sh7750_mem_writeb(void *opaque, target_phys_addr_t addr,
639 27c7ca7e bellard
                              uint32_t mem_value)
640 27c7ca7e bellard
{
641 27c7ca7e bellard
    SH7750State *s = opaque;
642 27c7ca7e bellard
643 27c7ca7e bellard
    switch (addr) {
644 27c7ca7e bellard
        /* PRECHARGE ? XXXXX */
645 27c7ca7e bellard
    case SH7750_PRECHARGE0_A7:
646 27c7ca7e bellard
    case SH7750_PRECHARGE1_A7:
647 27c7ca7e bellard
        ignore_access("byte write", addr);
648 27c7ca7e bellard
        return;
649 27c7ca7e bellard
    case SH7750_SCBRR2_A7:
650 27c7ca7e bellard
        s->scbrr2 = mem_value;
651 27c7ca7e bellard
        return;
652 27c7ca7e bellard
    case SH7750_TSTR_A7:
653 27c7ca7e bellard
        s->tstr = mem_value;
654 27c7ca7e bellard
        timer_start_changed(s);
655 27c7ca7e bellard
        return;
656 27c7ca7e bellard
    case SH7750_SCSCR1_A7:
657 27c7ca7e bellard
        s->scscr1 = mem_value;
658 27c7ca7e bellard
        scscr1_changed(s);
659 27c7ca7e bellard
        return;
660 27c7ca7e bellard
    case SH7750_SCSMR1_A7:
661 27c7ca7e bellard
        s->scsmr1 = mem_value;
662 27c7ca7e bellard
        return;
663 27c7ca7e bellard
    case SH7750_SCBRR1_A7:
664 27c7ca7e bellard
        s->scbrr1 = mem_value;
665 27c7ca7e bellard
        return;
666 27c7ca7e bellard
    case SH7750_SCTDR1_A7:
667 27c7ca7e bellard
        s->scssr1 &= ~SH7750_SCSSR1_TEND;
668 27c7ca7e bellard
        s->sctdr1 = mem_value;
669 27c7ca7e bellard
        return;
670 27c7ca7e bellard
    case SH7750_SCSSR1_A7:
671 27c7ca7e bellard
        serial1_change_scssr1(s, mem_value);
672 27c7ca7e bellard
        return;
673 27c7ca7e bellard
    default:
674 27c7ca7e bellard
        error_access("byte write", addr);
675 27c7ca7e bellard
        assert(0);
676 27c7ca7e bellard
    }
677 27c7ca7e bellard
}
678 27c7ca7e bellard
679 27c7ca7e bellard
static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr,
680 27c7ca7e bellard
                              uint32_t mem_value)
681 27c7ca7e bellard
{
682 27c7ca7e bellard
    SH7750State *s = opaque;
683 27c7ca7e bellard
    uint16_t temp;
684 27c7ca7e bellard
685 27c7ca7e bellard
    switch (addr) {
686 27c7ca7e bellard
        /* SDRAM controller */
687 27c7ca7e bellard
    case SH7750_SCBRR1_A7:
688 27c7ca7e bellard
    case SH7750_SCBRR2_A7:
689 27c7ca7e bellard
    case SH7750_BCR2_A7:
690 27c7ca7e bellard
    case SH7750_BCR3_A7:
691 27c7ca7e bellard
    case SH7750_RTCOR_A7:
692 27c7ca7e bellard
    case SH7750_RTCNT_A7:
693 27c7ca7e bellard
    case SH7750_RTCSR_A7:
694 27c7ca7e bellard
        ignore_access("word write", addr);
695 27c7ca7e bellard
        return;
696 27c7ca7e bellard
        /* IO ports */
697 27c7ca7e bellard
    case SH7750_PDTRA_A7:
698 27c7ca7e bellard
        temp = porta_lines(s);
699 27c7ca7e bellard
        s->pdtra = mem_value;
700 27c7ca7e bellard
        porta_changed(s, temp);
701 27c7ca7e bellard
        return;
702 27c7ca7e bellard
    case SH7750_PDTRB_A7:
703 27c7ca7e bellard
        temp = portb_lines(s);
704 27c7ca7e bellard
        s->pdtrb = mem_value;
705 27c7ca7e bellard
        portb_changed(s, temp);
706 27c7ca7e bellard
        return;
707 27c7ca7e bellard
    case SH7750_RFCR_A7:
708 27c7ca7e bellard
        fprintf(stderr, "Write access to refresh count register\n");
709 27c7ca7e bellard
        s->rfcr = mem_value;
710 27c7ca7e bellard
        return;
711 27c7ca7e bellard
    case SH7750_SCLSR2_A7:
712 27c7ca7e bellard
        s->sclsr2 = mem_value;
713 27c7ca7e bellard
        return;
714 27c7ca7e bellard
    case SH7750_SCSCR2_A7:
715 27c7ca7e bellard
        s->scscr2 = mem_value;
716 27c7ca7e bellard
        scscr2_changed(s);
717 27c7ca7e bellard
        return;
718 27c7ca7e bellard
    case SH7750_SCFCR2_A7:
719 27c7ca7e bellard
        s->scfcr2 = mem_value;
720 27c7ca7e bellard
        return;
721 27c7ca7e bellard
    case SH7750_SCSMR2_A7:
722 27c7ca7e bellard
        s->scsmr2 = mem_value;
723 27c7ca7e bellard
        return;
724 27c7ca7e bellard
    case SH7750_TCR0_A7:
725 27c7ca7e bellard
        s->tcr0 = mem_value;
726 27c7ca7e bellard
        return;
727 27c7ca7e bellard
    case SH7750_GPIOIC_A7:
728 27c7ca7e bellard
        s->gpioic = mem_value;
729 27c7ca7e bellard
        if (mem_value != 0) {
730 27c7ca7e bellard
            fprintf(stderr, "I/O interrupts not implemented\n");
731 27c7ca7e bellard
            assert(0);
732 27c7ca7e bellard
        }
733 27c7ca7e bellard
        return;
734 27c7ca7e bellard
    default:
735 27c7ca7e bellard
        error_access("word write", addr);
736 27c7ca7e bellard
        assert(0);
737 27c7ca7e bellard
    }
738 27c7ca7e bellard
}
739 27c7ca7e bellard
740 27c7ca7e bellard
static void sh7750_mem_writel(void *opaque, target_phys_addr_t addr,
741 27c7ca7e bellard
                              uint32_t mem_value)
742 27c7ca7e bellard
{
743 27c7ca7e bellard
    SH7750State *s = opaque;
744 27c7ca7e bellard
    uint16_t temp;
745 27c7ca7e bellard
746 27c7ca7e bellard
    switch (addr) {
747 27c7ca7e bellard
        /* SDRAM controller */
748 27c7ca7e bellard
    case SH7750_BCR1_A7:
749 27c7ca7e bellard
    case SH7750_BCR4_A7:
750 27c7ca7e bellard
    case SH7750_WCR1_A7:
751 27c7ca7e bellard
    case SH7750_WCR2_A7:
752 27c7ca7e bellard
    case SH7750_WCR3_A7:
753 27c7ca7e bellard
    case SH7750_MCR_A7:
754 27c7ca7e bellard
        ignore_access("long write", addr);
755 27c7ca7e bellard
        return;
756 27c7ca7e bellard
        /* IO ports */
757 27c7ca7e bellard
    case SH7750_PCTRA_A7:
758 27c7ca7e bellard
        temp = porta_lines(s);
759 27c7ca7e bellard
        s->pctra = mem_value;
760 27c7ca7e bellard
        s->portdira = portdir(mem_value);
761 27c7ca7e bellard
        s->portpullupa = portpullup(mem_value);
762 27c7ca7e bellard
        porta_changed(s, temp);
763 27c7ca7e bellard
        return;
764 27c7ca7e bellard
    case SH7750_PCTRB_A7:
765 27c7ca7e bellard
        temp = portb_lines(s);
766 27c7ca7e bellard
        s->pctrb = mem_value;
767 27c7ca7e bellard
        s->portdirb = portdir(mem_value);
768 27c7ca7e bellard
        s->portpullupb = portpullup(mem_value);
769 27c7ca7e bellard
        portb_changed(s, temp);
770 27c7ca7e bellard
        return;
771 27c7ca7e bellard
    case SH7750_TCNT0_A7:
772 27c7ca7e bellard
        s->tcnt0 = mem_value & 0xf;
773 27c7ca7e bellard
        return;
774 27c7ca7e bellard
    case SH7750_MMUCR_A7:
775 27c7ca7e bellard
        s->cpu->mmucr = mem_value;
776 27c7ca7e bellard
        return;
777 27c7ca7e bellard
    case SH7750_PTEH_A7:
778 27c7ca7e bellard
        s->cpu->pteh = mem_value;
779 27c7ca7e bellard
        return;
780 27c7ca7e bellard
    case SH7750_PTEL_A7:
781 27c7ca7e bellard
        s->cpu->ptel = mem_value;
782 27c7ca7e bellard
        return;
783 27c7ca7e bellard
    case SH7750_TTB_A7:
784 27c7ca7e bellard
        s->cpu->ttb = mem_value;
785 27c7ca7e bellard
        return;
786 27c7ca7e bellard
    case SH7750_TEA_A7:
787 27c7ca7e bellard
        s->cpu->tea = mem_value;
788 27c7ca7e bellard
        return;
789 27c7ca7e bellard
    case SH7750_TRA_A7:
790 27c7ca7e bellard
        s->cpu->tra = mem_value & 0x000007ff;
791 27c7ca7e bellard
        return;
792 27c7ca7e bellard
    case SH7750_EXPEVT_A7:
793 27c7ca7e bellard
        s->cpu->expevt = mem_value & 0x000007ff;
794 27c7ca7e bellard
        return;
795 27c7ca7e bellard
    case SH7750_INTEVT_A7:
796 27c7ca7e bellard
        s->cpu->intevt = mem_value & 0x000007ff;
797 27c7ca7e bellard
        return;
798 27c7ca7e bellard
    case SH7750_CCR_A7:
799 27c7ca7e bellard
        s->ccr = mem_value;
800 27c7ca7e bellard
        return;
801 27c7ca7e bellard
    default:
802 27c7ca7e bellard
        error_access("long write", addr);
803 27c7ca7e bellard
        assert(0);
804 27c7ca7e bellard
    }
805 27c7ca7e bellard
}
806 27c7ca7e bellard
807 27c7ca7e bellard
static CPUReadMemoryFunc *sh7750_mem_read[] = {
808 27c7ca7e bellard
    sh7750_mem_readb,
809 27c7ca7e bellard
    sh7750_mem_readw,
810 27c7ca7e bellard
    sh7750_mem_readl
811 27c7ca7e bellard
};
812 27c7ca7e bellard
813 27c7ca7e bellard
static CPUWriteMemoryFunc *sh7750_mem_write[] = {
814 27c7ca7e bellard
    sh7750_mem_writeb,
815 27c7ca7e bellard
    sh7750_mem_writew,
816 27c7ca7e bellard
    sh7750_mem_writel
817 27c7ca7e bellard
};
818 27c7ca7e bellard
819 27c7ca7e bellard
SH7750State *sh7750_init(CPUSH4State * cpu)
820 27c7ca7e bellard
{
821 27c7ca7e bellard
    SH7750State *s;
822 27c7ca7e bellard
    int sh7750_io_memory;
823 27c7ca7e bellard
824 27c7ca7e bellard
    s = qemu_mallocz(sizeof(SH7750State));
825 27c7ca7e bellard
    s->cpu = cpu;
826 27c7ca7e bellard
    s->periph_freq = 60000000;        /* 60MHz */
827 27c7ca7e bellard
    sh7750_io_memory = cpu_register_io_memory(0,
828 27c7ca7e bellard
                                              sh7750_mem_read,
829 27c7ca7e bellard
                                              sh7750_mem_write, s);
830 27c7ca7e bellard
    cpu_register_physical_memory(0x1c000000, 0x04000000, sh7750_io_memory);
831 27c7ca7e bellard
    init_timers(s);
832 27c7ca7e bellard
    init_serial_ports(s);
833 27c7ca7e bellard
    return s;
834 27c7ca7e bellard
}