]> git.proxmox.com Git - mirror_qemu.git/blob - hw/sh7750.c
C99 64 bit printf
[mirror_qemu.git] / 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 }