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