Statistics
| Branch: | Revision:

root / hw / sh7750.c @ 26a76461

History | View | Annotate | Download (20.6 kB)

1 27c7ca7e bellard
/*
2 27c7ca7e bellard
 * SH7750 device
3 27c7ca7e bellard
 * 
4 27c7ca7e bellard
 * Copyright (c) 2005 Samuel Tardieu
5 27c7ca7e bellard
 * 
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 27c7ca7e bellard
    qemu_chr_add_read_handler(chr, serial1_can_receive,
303 27c7ca7e bellard
                              serial1_receive, s);
304 27c7ca7e bellard
    qemu_chr_add_event_handler(chr, serial1_event);
305 27c7ca7e bellard
}
306 27c7ca7e bellard
307 27c7ca7e bellard
/**********************************************************************
308 27c7ca7e bellard
 Second serial port
309 27c7ca7e bellard
**********************************************************************/
310 27c7ca7e bellard
311 27c7ca7e bellard
static int serial2_can_receive(void *opaque)
312 27c7ca7e bellard
{
313 27c7ca7e bellard
    SH7750State *s = opaque;
314 27c7ca7e bellard
    static uint8_t max_fifo_size[] = { 15, 1, 4, 6, 8, 10, 12, 14 };
315 27c7ca7e bellard
316 27c7ca7e bellard
    return s->serial2_receive_fifo.length <
317 27c7ca7e bellard
        max_fifo_size[(s->scfcr2 >> 9) & 7];
318 27c7ca7e bellard
}
319 27c7ca7e bellard
320 27c7ca7e bellard
static void serial2_adjust_receive_flags(SH7750State * s)
321 27c7ca7e bellard
{
322 27c7ca7e bellard
    static uint8_t max_fifo_size[] = { 1, 4, 8, 14 };
323 27c7ca7e bellard
324 27c7ca7e bellard
    /* XXXXX Add interrupt generation */
325 27c7ca7e bellard
    if (s->serial2_receive_fifo.length >=
326 27c7ca7e bellard
        max_fifo_size[(s->scfcr2 >> 7) & 3]) {
327 27c7ca7e bellard
        s->scfsr2 |= SH7750_SCFSR2_RDF;
328 27c7ca7e bellard
        s->scfsr2 &= ~SH7750_SCFSR2_DR;
329 27c7ca7e bellard
    } else {
330 27c7ca7e bellard
        s->scfsr2 &= ~SH7750_SCFSR2_RDF;
331 27c7ca7e bellard
        if (s->serial2_receive_fifo.length > 0)
332 27c7ca7e bellard
            s->scfsr2 |= SH7750_SCFSR2_DR;
333 27c7ca7e bellard
        else
334 27c7ca7e bellard
            s->scfsr2 &= ~SH7750_SCFSR2_DR;
335 27c7ca7e bellard
    }
336 27c7ca7e bellard
}
337 27c7ca7e bellard
338 27c7ca7e bellard
static void serial2_append_char(SH7750State * s, uint8_t c)
339 27c7ca7e bellard
{
340 27c7ca7e bellard
    if (s->serial2_receive_fifo.length == 16) {
341 27c7ca7e bellard
        /* Overflow */
342 27c7ca7e bellard
        s->sclsr2 |= SH7750_SCLSR2_ORER;
343 27c7ca7e bellard
        return;
344 27c7ca7e bellard
    }
345 27c7ca7e bellard
346 27c7ca7e bellard
    s->serial2_receive_fifo.data[s->serial2_receive_fifo.write_idx++] = c;
347 27c7ca7e bellard
    s->serial2_receive_fifo.length++;
348 27c7ca7e bellard
    serial2_adjust_receive_flags(s);
349 27c7ca7e bellard
}
350 27c7ca7e bellard
351 27c7ca7e bellard
static void serial2_receive(void *opaque, const uint8_t * buf, int size)
352 27c7ca7e bellard
{
353 27c7ca7e bellard
    SH7750State *s = opaque;
354 27c7ca7e bellard
    int i;
355 27c7ca7e bellard
356 27c7ca7e bellard
    for (i = 0; i < size; i++)
357 27c7ca7e bellard
        serial2_append_char(s, buf[i]);
358 27c7ca7e bellard
}
359 27c7ca7e bellard
360 27c7ca7e bellard
static void serial2_event(void *opaque, int event)
361 27c7ca7e bellard
{
362 27c7ca7e bellard
    /* XXXXX */
363 27c7ca7e bellard
    assert(0);
364 27c7ca7e bellard
}
365 27c7ca7e bellard
366 27c7ca7e bellard
static void serial2_update_parameters(SH7750State * s)
367 27c7ca7e bellard
{
368 27c7ca7e bellard
    QEMUSerialSetParams ssp;
369 27c7ca7e bellard
370 27c7ca7e bellard
    if (s->scsmr2 & SH7750_SCSMR_CHR_7)
371 27c7ca7e bellard
        ssp.data_bits = 7;
372 27c7ca7e bellard
    else
373 27c7ca7e bellard
        ssp.data_bits = 8;
374 27c7ca7e bellard
    if (s->scsmr2 & SH7750_SCSMR_PE) {
375 27c7ca7e bellard
        if (s->scsmr2 & SH7750_SCSMR_PM_ODD)
376 27c7ca7e bellard
            ssp.parity = 'O';
377 27c7ca7e bellard
        else
378 27c7ca7e bellard
            ssp.parity = 'E';
379 27c7ca7e bellard
    } else
380 27c7ca7e bellard
        ssp.parity = 'N';
381 27c7ca7e bellard
    if (s->scsmr2 & SH7750_SCSMR_STOP_2)
382 27c7ca7e bellard
        ssp.stop_bits = 2;
383 27c7ca7e bellard
    else
384 27c7ca7e bellard
        ssp.stop_bits = 1;
385 27c7ca7e bellard
    fprintf(stderr, "SCSMR2=%04x SCBRR2=%02x\n", s->scsmr2, s->scbrr2);
386 27c7ca7e bellard
    ssp.speed = s->periph_freq /
387 27c7ca7e bellard
        (32 * s->scbrr2 * (1 << (2 * (s->scsmr2 & 3)))) - 1;
388 27c7ca7e bellard
    fprintf(stderr, "data bits=%d, stop bits=%d, parity=%c, speed=%d\n",
389 27c7ca7e bellard
            ssp.data_bits, ssp.stop_bits, ssp.parity, ssp.speed);
390 27c7ca7e bellard
    qemu_chr_ioctl(s->serial2, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
391 27c7ca7e bellard
}
392 27c7ca7e bellard
393 27c7ca7e bellard
static void scscr2_changed(SH7750State * s)
394 27c7ca7e bellard
{
395 27c7ca7e bellard
    if (s->scscr2 & (SH7750_SCSCR_TE | SH7750_SCSCR_RE)) {
396 27c7ca7e bellard
        if (!s->serial2) {
397 27c7ca7e bellard
            fprintf(stderr, "serial port 2 not bound to anything\n");
398 27c7ca7e bellard
            assert(0);
399 27c7ca7e bellard
        }
400 27c7ca7e bellard
        serial2_update_parameters(s);
401 27c7ca7e bellard
    }
402 27c7ca7e bellard
}
403 27c7ca7e bellard
404 27c7ca7e bellard
static void init_serial2(SH7750State * s, int serial_nb)
405 27c7ca7e bellard
{
406 27c7ca7e bellard
    CharDriverState *chr;
407 27c7ca7e bellard
408 27c7ca7e bellard
    s->scfsr2 = 0x0060;
409 27c7ca7e bellard
410 27c7ca7e bellard
    chr = serial_hds[serial_nb];
411 27c7ca7e bellard
    if (!chr) {
412 27c7ca7e bellard
        fprintf(stderr,
413 27c7ca7e bellard
                "no serial port associated to SH7750 second serial port\n");
414 27c7ca7e bellard
        return;
415 27c7ca7e bellard
    }
416 27c7ca7e bellard
417 27c7ca7e bellard
    s->serial2 = chr;
418 27c7ca7e bellard
    qemu_chr_add_read_handler(chr, serial2_can_receive,
419 27c7ca7e bellard
                              serial2_receive, s);
420 27c7ca7e bellard
    qemu_chr_add_event_handler(chr, serial2_event);
421 27c7ca7e bellard
}
422 27c7ca7e bellard
423 27c7ca7e bellard
static void init_serial_ports(SH7750State * s)
424 27c7ca7e bellard
{
425 27c7ca7e bellard
    init_serial1(s, 0);
426 27c7ca7e bellard
    init_serial2(s, 1);
427 27c7ca7e bellard
}
428 27c7ca7e bellard
429 27c7ca7e bellard
/**********************************************************************
430 27c7ca7e bellard
 I/O ports
431 27c7ca7e bellard
**********************************************************************/
432 27c7ca7e bellard
433 27c7ca7e bellard
int sh7750_register_io_device(SH7750State * s, sh7750_io_device * device)
434 27c7ca7e bellard
{
435 27c7ca7e bellard
    int i;
436 27c7ca7e bellard
437 27c7ca7e bellard
    for (i = 0; i < NB_DEVICES; i++) {
438 27c7ca7e bellard
        if (s->devices[i] == NULL) {
439 27c7ca7e bellard
            s->devices[i] = device;
440 27c7ca7e bellard
            return 0;
441 27c7ca7e bellard
        }
442 27c7ca7e bellard
    }
443 27c7ca7e bellard
    return -1;
444 27c7ca7e bellard
}
445 27c7ca7e bellard
446 27c7ca7e bellard
static uint16_t portdir(uint32_t v)
447 27c7ca7e bellard
{
448 27c7ca7e bellard
#define EVENPORTMASK(n) ((v & (1<<((n)<<1))) >> (n))
449 27c7ca7e bellard
    return
450 27c7ca7e bellard
        EVENPORTMASK(15) | EVENPORTMASK(14) | EVENPORTMASK(13) |
451 27c7ca7e bellard
        EVENPORTMASK(12) | EVENPORTMASK(11) | EVENPORTMASK(10) |
452 27c7ca7e bellard
        EVENPORTMASK(9) | EVENPORTMASK(8) | EVENPORTMASK(7) |
453 27c7ca7e bellard
        EVENPORTMASK(6) | EVENPORTMASK(5) | EVENPORTMASK(4) |
454 27c7ca7e bellard
        EVENPORTMASK(3) | EVENPORTMASK(2) | EVENPORTMASK(1) |
455 27c7ca7e bellard
        EVENPORTMASK(0);
456 27c7ca7e bellard
}
457 27c7ca7e bellard
458 27c7ca7e bellard
static uint16_t portpullup(uint32_t v)
459 27c7ca7e bellard
{
460 27c7ca7e bellard
#define ODDPORTMASK(n) ((v & (1<<(((n)<<1)+1))) >> (n))
461 27c7ca7e bellard
    return
462 27c7ca7e bellard
        ODDPORTMASK(15) | ODDPORTMASK(14) | ODDPORTMASK(13) |
463 27c7ca7e bellard
        ODDPORTMASK(12) | ODDPORTMASK(11) | ODDPORTMASK(10) |
464 27c7ca7e bellard
        ODDPORTMASK(9) | ODDPORTMASK(8) | ODDPORTMASK(7) | ODDPORTMASK(6) |
465 27c7ca7e bellard
        ODDPORTMASK(5) | ODDPORTMASK(4) | ODDPORTMASK(3) | ODDPORTMASK(2) |
466 27c7ca7e bellard
        ODDPORTMASK(1) | ODDPORTMASK(0);
467 27c7ca7e bellard
}
468 27c7ca7e bellard
469 27c7ca7e bellard
static uint16_t porta_lines(SH7750State * s)
470 27c7ca7e bellard
{
471 27c7ca7e bellard
    return (s->portdira & s->pdtra) |        /* CPU */
472 27c7ca7e bellard
        (s->periph_portdira & s->periph_pdtra) |        /* Peripherals */
473 27c7ca7e bellard
        (~(s->portdira | s->periph_portdira) & s->portpullupa);        /* Pullups */
474 27c7ca7e bellard
}
475 27c7ca7e bellard
476 27c7ca7e bellard
static uint16_t portb_lines(SH7750State * s)
477 27c7ca7e bellard
{
478 27c7ca7e bellard
    return (s->portdirb & s->pdtrb) |        /* CPU */
479 27c7ca7e bellard
        (s->periph_portdirb & s->periph_pdtrb) |        /* Peripherals */
480 27c7ca7e bellard
        (~(s->portdirb | s->periph_portdirb) & s->portpullupb);        /* Pullups */
481 27c7ca7e bellard
}
482 27c7ca7e bellard
483 27c7ca7e bellard
static void gen_port_interrupts(SH7750State * s)
484 27c7ca7e bellard
{
485 27c7ca7e bellard
    /* XXXXX interrupts not generated */
486 27c7ca7e bellard
}
487 27c7ca7e bellard
488 27c7ca7e bellard
static void porta_changed(SH7750State * s, uint16_t prev)
489 27c7ca7e bellard
{
490 27c7ca7e bellard
    uint16_t currenta, changes;
491 27c7ca7e bellard
    int i, r = 0;
492 27c7ca7e bellard
493 27c7ca7e bellard
#if 0
494 27c7ca7e bellard
    fprintf(stderr, "porta changed from 0x%04x to 0x%04x\n",
495 27c7ca7e bellard
            prev, porta_lines(s));
496 27c7ca7e bellard
    fprintf(stderr, "pdtra=0x%04x, pctra=0x%08x\n", s->pdtra, s->pctra);
497 27c7ca7e bellard
#endif
498 27c7ca7e bellard
    currenta = porta_lines(s);
499 27c7ca7e bellard
    if (currenta == prev)
500 27c7ca7e bellard
        return;
501 27c7ca7e bellard
    changes = currenta ^ prev;
502 27c7ca7e bellard
503 27c7ca7e bellard
    for (i = 0; i < NB_DEVICES; i++) {
504 27c7ca7e bellard
        if (s->devices[i] && (s->devices[i]->portamask_trigger & changes)) {
505 27c7ca7e bellard
            r |= s->devices[i]->port_change_cb(currenta, portb_lines(s),
506 27c7ca7e bellard
                                               &s->periph_pdtra,
507 27c7ca7e bellard
                                               &s->periph_portdira,
508 27c7ca7e bellard
                                               &s->periph_pdtrb,
509 27c7ca7e bellard
                                               &s->periph_portdirb);
510 27c7ca7e bellard
        }
511 27c7ca7e bellard
    }
512 27c7ca7e bellard
513 27c7ca7e bellard
    if (r)
514 27c7ca7e bellard
        gen_port_interrupts(s);
515 27c7ca7e bellard
}
516 27c7ca7e bellard
517 27c7ca7e bellard
static void portb_changed(SH7750State * s, uint16_t prev)
518 27c7ca7e bellard
{
519 27c7ca7e bellard
    uint16_t currentb, changes;
520 27c7ca7e bellard
    int i, r = 0;
521 27c7ca7e bellard
522 27c7ca7e bellard
    currentb = portb_lines(s);
523 27c7ca7e bellard
    if (currentb == prev)
524 27c7ca7e bellard
        return;
525 27c7ca7e bellard
    changes = currentb ^ prev;
526 27c7ca7e bellard
527 27c7ca7e bellard
    for (i = 0; i < NB_DEVICES; i++) {
528 27c7ca7e bellard
        if (s->devices[i] && (s->devices[i]->portbmask_trigger & changes)) {
529 27c7ca7e bellard
            r |= s->devices[i]->port_change_cb(portb_lines(s), currentb,
530 27c7ca7e bellard
                                               &s->periph_pdtra,
531 27c7ca7e bellard
                                               &s->periph_portdira,
532 27c7ca7e bellard
                                               &s->periph_pdtrb,
533 27c7ca7e bellard
                                               &s->periph_portdirb);
534 27c7ca7e bellard
        }
535 27c7ca7e bellard
    }
536 27c7ca7e bellard
537 27c7ca7e bellard
    if (r)
538 27c7ca7e bellard
        gen_port_interrupts(s);
539 27c7ca7e bellard
}
540 27c7ca7e bellard
541 27c7ca7e bellard
/**********************************************************************
542 27c7ca7e bellard
 Memory
543 27c7ca7e bellard
**********************************************************************/
544 27c7ca7e bellard
545 27c7ca7e bellard
static void error_access(const char *kind, target_phys_addr_t addr)
546 27c7ca7e bellard
{
547 27c7ca7e bellard
    fprintf(stderr, "%s to %s (0x%08x) not supported\n",
548 27c7ca7e bellard
            kind, regname(addr), addr);
549 27c7ca7e bellard
}
550 27c7ca7e bellard
551 27c7ca7e bellard
static void ignore_access(const char *kind, target_phys_addr_t addr)
552 27c7ca7e bellard
{
553 27c7ca7e bellard
    fprintf(stderr, "%s to %s (0x%08x) ignored\n",
554 27c7ca7e bellard
            kind, regname(addr), addr);
555 27c7ca7e bellard
}
556 27c7ca7e bellard
557 27c7ca7e bellard
static uint32_t sh7750_mem_readb(void *opaque, target_phys_addr_t addr)
558 27c7ca7e bellard
{
559 27c7ca7e bellard
    SH7750State *s = opaque;
560 27c7ca7e bellard
    uint8_t r;
561 27c7ca7e bellard
562 27c7ca7e bellard
    switch (addr) {
563 27c7ca7e bellard
    case SH7750_SCSSR1_A7:
564 27c7ca7e bellard
        r = s->scssr1;
565 27c7ca7e bellard
        s->scssr1_read |= r;
566 27c7ca7e bellard
        return s->scssr1;
567 27c7ca7e bellard
    case SH7750_SCRDR1_A7:
568 27c7ca7e bellard
        s->scssr1 &= ~SH7750_SCSSR1_RDRF;
569 27c7ca7e bellard
        return s->scrdr1;
570 27c7ca7e bellard
    default:
571 27c7ca7e bellard
        error_access("byte read", addr);
572 27c7ca7e bellard
        assert(0);
573 27c7ca7e bellard
    }
574 27c7ca7e bellard
}
575 27c7ca7e bellard
576 27c7ca7e bellard
static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr)
577 27c7ca7e bellard
{
578 27c7ca7e bellard
    SH7750State *s = opaque;
579 27c7ca7e bellard
    uint16_t r;
580 27c7ca7e bellard
581 27c7ca7e bellard
    switch (addr) {
582 27c7ca7e bellard
    case SH7750_RFCR_A7:
583 27c7ca7e bellard
        fprintf(stderr,
584 27c7ca7e bellard
                "Read access to refresh count register, incrementing\n");
585 27c7ca7e bellard
        return s->rfcr++;
586 27c7ca7e bellard
    case SH7750_TCR0_A7:
587 27c7ca7e bellard
        return s->tcr0;
588 27c7ca7e bellard
    case SH7750_SCLSR2_A7:
589 27c7ca7e bellard
        /* Read and clear overflow bit */
590 27c7ca7e bellard
        r = s->sclsr2;
591 27c7ca7e bellard
        s->sclsr2 = 0;
592 27c7ca7e bellard
        return r;
593 27c7ca7e bellard
    case SH7750_SCSFR2_A7:
594 27c7ca7e bellard
        return s->scfsr2;
595 27c7ca7e bellard
    case SH7750_PDTRA_A7:
596 27c7ca7e bellard
        return porta_lines(s);
597 27c7ca7e bellard
    case SH7750_PDTRB_A7:
598 27c7ca7e bellard
        return portb_lines(s);
599 27c7ca7e bellard
    default:
600 27c7ca7e bellard
        error_access("word read", addr);
601 27c7ca7e bellard
        assert(0);
602 27c7ca7e bellard
    }
603 27c7ca7e bellard
}
604 27c7ca7e bellard
605 27c7ca7e bellard
static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr)
606 27c7ca7e bellard
{
607 27c7ca7e bellard
    SH7750State *s = opaque;
608 27c7ca7e bellard
609 27c7ca7e bellard
    switch (addr) {
610 27c7ca7e bellard
    case SH7750_MMUCR_A7:
611 27c7ca7e bellard
        return s->cpu->mmucr;
612 27c7ca7e bellard
    case SH7750_PTEH_A7:
613 27c7ca7e bellard
        return s->cpu->pteh;
614 27c7ca7e bellard
    case SH7750_PTEL_A7:
615 27c7ca7e bellard
        return s->cpu->ptel;
616 27c7ca7e bellard
    case SH7750_TTB_A7:
617 27c7ca7e bellard
        return s->cpu->ttb;
618 27c7ca7e bellard
    case SH7750_TEA_A7:
619 27c7ca7e bellard
        return s->cpu->tea;
620 27c7ca7e bellard
    case SH7750_TRA_A7:
621 27c7ca7e bellard
        return s->cpu->tra;
622 27c7ca7e bellard
    case SH7750_EXPEVT_A7:
623 27c7ca7e bellard
        return s->cpu->expevt;
624 27c7ca7e bellard
    case SH7750_INTEVT_A7:
625 27c7ca7e bellard
        return s->cpu->intevt;
626 27c7ca7e bellard
    case SH7750_CCR_A7:
627 27c7ca7e bellard
        return s->ccr;
628 27c7ca7e bellard
    case 0x1f000030:                /* Processor version PVR */
629 27c7ca7e bellard
        return 0x00050000;        /* SH7750R */
630 27c7ca7e bellard
    case 0x1f000040:                /* Processor version CVR */
631 27c7ca7e bellard
        return 0x00110000;        /* Minimum caches */
632 27c7ca7e bellard
    case 0x1f000044:                /* Processor version PRR */
633 27c7ca7e bellard
        return 0x00000100;        /* SH7750R */
634 27c7ca7e bellard
    default:
635 27c7ca7e bellard
        error_access("long read", addr);
636 27c7ca7e bellard
        assert(0);
637 27c7ca7e bellard
    }
638 27c7ca7e bellard
}
639 27c7ca7e bellard
640 27c7ca7e bellard
static void sh7750_mem_writeb(void *opaque, target_phys_addr_t addr,
641 27c7ca7e bellard
                              uint32_t mem_value)
642 27c7ca7e bellard
{
643 27c7ca7e bellard
    SH7750State *s = opaque;
644 27c7ca7e bellard
645 27c7ca7e bellard
    switch (addr) {
646 27c7ca7e bellard
        /* PRECHARGE ? XXXXX */
647 27c7ca7e bellard
    case SH7750_PRECHARGE0_A7:
648 27c7ca7e bellard
    case SH7750_PRECHARGE1_A7:
649 27c7ca7e bellard
        ignore_access("byte write", addr);
650 27c7ca7e bellard
        return;
651 27c7ca7e bellard
    case SH7750_SCBRR2_A7:
652 27c7ca7e bellard
        s->scbrr2 = mem_value;
653 27c7ca7e bellard
        return;
654 27c7ca7e bellard
    case SH7750_TSTR_A7:
655 27c7ca7e bellard
        s->tstr = mem_value;
656 27c7ca7e bellard
        timer_start_changed(s);
657 27c7ca7e bellard
        return;
658 27c7ca7e bellard
    case SH7750_SCSCR1_A7:
659 27c7ca7e bellard
        s->scscr1 = mem_value;
660 27c7ca7e bellard
        scscr1_changed(s);
661 27c7ca7e bellard
        return;
662 27c7ca7e bellard
    case SH7750_SCSMR1_A7:
663 27c7ca7e bellard
        s->scsmr1 = mem_value;
664 27c7ca7e bellard
        return;
665 27c7ca7e bellard
    case SH7750_SCBRR1_A7:
666 27c7ca7e bellard
        s->scbrr1 = mem_value;
667 27c7ca7e bellard
        return;
668 27c7ca7e bellard
    case SH7750_SCTDR1_A7:
669 27c7ca7e bellard
        s->scssr1 &= ~SH7750_SCSSR1_TEND;
670 27c7ca7e bellard
        s->sctdr1 = mem_value;
671 27c7ca7e bellard
        return;
672 27c7ca7e bellard
    case SH7750_SCSSR1_A7:
673 27c7ca7e bellard
        serial1_change_scssr1(s, mem_value);
674 27c7ca7e bellard
        return;
675 27c7ca7e bellard
    default:
676 27c7ca7e bellard
        error_access("byte write", addr);
677 27c7ca7e bellard
        assert(0);
678 27c7ca7e bellard
    }
679 27c7ca7e bellard
}
680 27c7ca7e bellard
681 27c7ca7e bellard
static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr,
682 27c7ca7e bellard
                              uint32_t mem_value)
683 27c7ca7e bellard
{
684 27c7ca7e bellard
    SH7750State *s = opaque;
685 27c7ca7e bellard
    uint16_t temp;
686 27c7ca7e bellard
687 27c7ca7e bellard
    switch (addr) {
688 27c7ca7e bellard
        /* SDRAM controller */
689 27c7ca7e bellard
    case SH7750_SCBRR1_A7:
690 27c7ca7e bellard
    case SH7750_SCBRR2_A7:
691 27c7ca7e bellard
    case SH7750_BCR2_A7:
692 27c7ca7e bellard
    case SH7750_BCR3_A7:
693 27c7ca7e bellard
    case SH7750_RTCOR_A7:
694 27c7ca7e bellard
    case SH7750_RTCNT_A7:
695 27c7ca7e bellard
    case SH7750_RTCSR_A7:
696 27c7ca7e bellard
        ignore_access("word write", addr);
697 27c7ca7e bellard
        return;
698 27c7ca7e bellard
        /* IO ports */
699 27c7ca7e bellard
    case SH7750_PDTRA_A7:
700 27c7ca7e bellard
        temp = porta_lines(s);
701 27c7ca7e bellard
        s->pdtra = mem_value;
702 27c7ca7e bellard
        porta_changed(s, temp);
703 27c7ca7e bellard
        return;
704 27c7ca7e bellard
    case SH7750_PDTRB_A7:
705 27c7ca7e bellard
        temp = portb_lines(s);
706 27c7ca7e bellard
        s->pdtrb = mem_value;
707 27c7ca7e bellard
        portb_changed(s, temp);
708 27c7ca7e bellard
        return;
709 27c7ca7e bellard
    case SH7750_RFCR_A7:
710 27c7ca7e bellard
        fprintf(stderr, "Write access to refresh count register\n");
711 27c7ca7e bellard
        s->rfcr = mem_value;
712 27c7ca7e bellard
        return;
713 27c7ca7e bellard
    case SH7750_SCLSR2_A7:
714 27c7ca7e bellard
        s->sclsr2 = mem_value;
715 27c7ca7e bellard
        return;
716 27c7ca7e bellard
    case SH7750_SCSCR2_A7:
717 27c7ca7e bellard
        s->scscr2 = mem_value;
718 27c7ca7e bellard
        scscr2_changed(s);
719 27c7ca7e bellard
        return;
720 27c7ca7e bellard
    case SH7750_SCFCR2_A7:
721 27c7ca7e bellard
        s->scfcr2 = mem_value;
722 27c7ca7e bellard
        return;
723 27c7ca7e bellard
    case SH7750_SCSMR2_A7:
724 27c7ca7e bellard
        s->scsmr2 = mem_value;
725 27c7ca7e bellard
        return;
726 27c7ca7e bellard
    case SH7750_TCR0_A7:
727 27c7ca7e bellard
        s->tcr0 = mem_value;
728 27c7ca7e bellard
        return;
729 27c7ca7e bellard
    case SH7750_GPIOIC_A7:
730 27c7ca7e bellard
        s->gpioic = mem_value;
731 27c7ca7e bellard
        if (mem_value != 0) {
732 27c7ca7e bellard
            fprintf(stderr, "I/O interrupts not implemented\n");
733 27c7ca7e bellard
            assert(0);
734 27c7ca7e bellard
        }
735 27c7ca7e bellard
        return;
736 27c7ca7e bellard
    default:
737 27c7ca7e bellard
        error_access("word write", addr);
738 27c7ca7e bellard
        assert(0);
739 27c7ca7e bellard
    }
740 27c7ca7e bellard
}
741 27c7ca7e bellard
742 27c7ca7e bellard
static void sh7750_mem_writel(void *opaque, target_phys_addr_t addr,
743 27c7ca7e bellard
                              uint32_t mem_value)
744 27c7ca7e bellard
{
745 27c7ca7e bellard
    SH7750State *s = opaque;
746 27c7ca7e bellard
    uint16_t temp;
747 27c7ca7e bellard
748 27c7ca7e bellard
    switch (addr) {
749 27c7ca7e bellard
        /* SDRAM controller */
750 27c7ca7e bellard
    case SH7750_BCR1_A7:
751 27c7ca7e bellard
    case SH7750_BCR4_A7:
752 27c7ca7e bellard
    case SH7750_WCR1_A7:
753 27c7ca7e bellard
    case SH7750_WCR2_A7:
754 27c7ca7e bellard
    case SH7750_WCR3_A7:
755 27c7ca7e bellard
    case SH7750_MCR_A7:
756 27c7ca7e bellard
        ignore_access("long write", addr);
757 27c7ca7e bellard
        return;
758 27c7ca7e bellard
        /* IO ports */
759 27c7ca7e bellard
    case SH7750_PCTRA_A7:
760 27c7ca7e bellard
        temp = porta_lines(s);
761 27c7ca7e bellard
        s->pctra = mem_value;
762 27c7ca7e bellard
        s->portdira = portdir(mem_value);
763 27c7ca7e bellard
        s->portpullupa = portpullup(mem_value);
764 27c7ca7e bellard
        porta_changed(s, temp);
765 27c7ca7e bellard
        return;
766 27c7ca7e bellard
    case SH7750_PCTRB_A7:
767 27c7ca7e bellard
        temp = portb_lines(s);
768 27c7ca7e bellard
        s->pctrb = mem_value;
769 27c7ca7e bellard
        s->portdirb = portdir(mem_value);
770 27c7ca7e bellard
        s->portpullupb = portpullup(mem_value);
771 27c7ca7e bellard
        portb_changed(s, temp);
772 27c7ca7e bellard
        return;
773 27c7ca7e bellard
    case SH7750_TCNT0_A7:
774 27c7ca7e bellard
        s->tcnt0 = mem_value & 0xf;
775 27c7ca7e bellard
        return;
776 27c7ca7e bellard
    case SH7750_MMUCR_A7:
777 27c7ca7e bellard
        s->cpu->mmucr = mem_value;
778 27c7ca7e bellard
        return;
779 27c7ca7e bellard
    case SH7750_PTEH_A7:
780 27c7ca7e bellard
        s->cpu->pteh = mem_value;
781 27c7ca7e bellard
        return;
782 27c7ca7e bellard
    case SH7750_PTEL_A7:
783 27c7ca7e bellard
        s->cpu->ptel = mem_value;
784 27c7ca7e bellard
        return;
785 27c7ca7e bellard
    case SH7750_TTB_A7:
786 27c7ca7e bellard
        s->cpu->ttb = mem_value;
787 27c7ca7e bellard
        return;
788 27c7ca7e bellard
    case SH7750_TEA_A7:
789 27c7ca7e bellard
        s->cpu->tea = mem_value;
790 27c7ca7e bellard
        return;
791 27c7ca7e bellard
    case SH7750_TRA_A7:
792 27c7ca7e bellard
        s->cpu->tra = mem_value & 0x000007ff;
793 27c7ca7e bellard
        return;
794 27c7ca7e bellard
    case SH7750_EXPEVT_A7:
795 27c7ca7e bellard
        s->cpu->expevt = mem_value & 0x000007ff;
796 27c7ca7e bellard
        return;
797 27c7ca7e bellard
    case SH7750_INTEVT_A7:
798 27c7ca7e bellard
        s->cpu->intevt = mem_value & 0x000007ff;
799 27c7ca7e bellard
        return;
800 27c7ca7e bellard
    case SH7750_CCR_A7:
801 27c7ca7e bellard
        s->ccr = mem_value;
802 27c7ca7e bellard
        return;
803 27c7ca7e bellard
    default:
804 27c7ca7e bellard
        error_access("long write", addr);
805 27c7ca7e bellard
        assert(0);
806 27c7ca7e bellard
    }
807 27c7ca7e bellard
}
808 27c7ca7e bellard
809 27c7ca7e bellard
static CPUReadMemoryFunc *sh7750_mem_read[] = {
810 27c7ca7e bellard
    sh7750_mem_readb,
811 27c7ca7e bellard
    sh7750_mem_readw,
812 27c7ca7e bellard
    sh7750_mem_readl
813 27c7ca7e bellard
};
814 27c7ca7e bellard
815 27c7ca7e bellard
static CPUWriteMemoryFunc *sh7750_mem_write[] = {
816 27c7ca7e bellard
    sh7750_mem_writeb,
817 27c7ca7e bellard
    sh7750_mem_writew,
818 27c7ca7e bellard
    sh7750_mem_writel
819 27c7ca7e bellard
};
820 27c7ca7e bellard
821 27c7ca7e bellard
SH7750State *sh7750_init(CPUSH4State * cpu)
822 27c7ca7e bellard
{
823 27c7ca7e bellard
    SH7750State *s;
824 27c7ca7e bellard
    int sh7750_io_memory;
825 27c7ca7e bellard
826 27c7ca7e bellard
    s = qemu_mallocz(sizeof(SH7750State));
827 27c7ca7e bellard
    s->cpu = cpu;
828 27c7ca7e bellard
    s->periph_freq = 60000000;        /* 60MHz */
829 27c7ca7e bellard
    sh7750_io_memory = cpu_register_io_memory(0,
830 27c7ca7e bellard
                                              sh7750_mem_read,
831 27c7ca7e bellard
                                              sh7750_mem_write, s);
832 27c7ca7e bellard
    cpu_register_physical_memory(0x1c000000, 0x04000000, sh7750_io_memory);
833 27c7ca7e bellard
    init_timers(s);
834 27c7ca7e bellard
    init_serial_ports(s);
835 27c7ca7e bellard
    return s;
836 27c7ca7e bellard
}