4 * Copyright (c) 2005 Samuel Tardieu
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
27 #include "sh7750_regs.h"
28 #include "sh7750_regnames.h"
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 */
39 typedef struct SH7750State
{
42 /* Peripheral frequency in Hz */
44 /* SDRAM controller */
46 /* First serial port */
47 CharDriverState
*serial1
;
54 uint8_t sctsr1_loaded
;
57 /* Second serial port */
58 CharDriverState
*serial2
;
65 fifo serial2_receive_fifo
;
66 fifo serial2_transmit_fifo
;
71 uint16_t portdira
; /* Cached */
72 uint16_t portpullupa
; /* Cached */
73 uint16_t portdirb
; /* Cached */
74 uint16_t portpullupb
; /* Cached */
77 uint16_t periph_pdtra
; /* Imposed by the peripherals */
78 uint16_t periph_portdira
; /* Direction seen from the peripherals */
79 uint16_t periph_pdtrb
; /* Imposed by the peripherals */
80 uint16_t periph_portdirb
; /* Direction seen from the peripherals */
81 sh7750_io_device
*devices
[NB_DEVICES
]; /* External peripherals */
87 /**********************************************************************
89 **********************************************************************/
91 static int serial1_can_receive(void *opaque
)
93 SH7750State
*s
= opaque
;
95 return s
->scscr1
& SH7750_SCSCR_RE
;
98 static void serial1_receive_char(SH7750State
* s
, uint8_t c
)
100 if (s
->scssr1
& SH7750_SCSSR1_RDRF
) {
101 s
->scssr1
|= SH7750_SCSSR1_ORER
;
106 s
->scssr1
|= SH7750_SCSSR1_RDRF
;
109 static void serial1_receive(void *opaque
, const uint8_t * buf
, int size
)
111 SH7750State
*s
= opaque
;
114 for (i
= 0; i
< size
; i
++) {
115 serial1_receive_char(s
, buf
[i
]);
119 static void serial1_event(void *opaque
, int event
)
124 static void serial1_maybe_send(SH7750State
* s
)
128 if (s
->scssr1
& SH7750_SCSSR1_TDRE
)
131 s
->scssr1
|= SH7750_SCSSR1_TDRE
| SH7750_SCSSR1_TEND
;
132 if (s
->scscr1
& SH7750_SCSCR_TIE
) {
133 fprintf(stderr
, "interrupts for serial port 1 not implemented\n");
136 /* XXXXX Check for errors in write */
137 qemu_chr_write(s
->serial1
, &c
, 1);
140 static void serial1_change_scssr1(SH7750State
* s
, uint8_t mem_value
)
144 /* If transmit disable, TDRE and TEND stays up */
145 if ((s
->scscr1
& SH7750_SCSCR_TE
) == 0) {
146 mem_value
|= SH7750_SCSSR1_TDRE
| SH7750_SCSSR1_TEND
;
149 /* Only clear bits which have been read before and do not set any bit
151 new_flags
= s
->scssr1
& ~s
->scssr1_read
; /* Preserve unread flags */
152 new_flags
&= mem_value
| ~s
->scssr1_read
; /* Clear read flags */
154 s
->scssr1
= (new_flags
& 0xf8) | (mem_value
& 1);
155 s
->scssr1_read
&= mem_value
;
157 /* If TDRE has been cleared, TEND will also be cleared */
158 if ((s
->scssr1
& SH7750_SCSSR1_TDRE
) == 0) {
159 s
->scssr1
&= ~SH7750_SCSSR1_TEND
;
162 /* Check for transmission to start */
163 serial1_maybe_send(s
);
166 static void serial1_update_parameters(SH7750State
* s
)
168 QEMUSerialSetParams ssp
;
170 if (s
->scsmr1
& SH7750_SCSMR_CHR_7
)
174 if (s
->scsmr1
& SH7750_SCSMR_PE
) {
175 if (s
->scsmr1
& SH7750_SCSMR_PM_ODD
)
181 if (s
->scsmr1
& SH7750_SCSMR_STOP_2
)
185 fprintf(stderr
, "SCSMR1=%04x SCBRR1=%02x\n", s
->scsmr1
, s
->scbrr1
);
186 ssp
.speed
= s
->periph_freq
/
187 (32 * s
->scbrr1
* (1 << (2 * (s
->scsmr1
& 3)))) - 1;
188 fprintf(stderr
, "data bits=%d, stop bits=%d, parity=%c, speed=%d\n",
189 ssp
.data_bits
, ssp
.stop_bits
, ssp
.parity
, ssp
.speed
);
190 qemu_chr_ioctl(s
->serial1
, CHR_IOCTL_SERIAL_SET_PARAMS
, &ssp
);
193 static void scscr1_changed(SH7750State
* s
)
195 if (s
->scscr1
& (SH7750_SCSCR_TE
| SH7750_SCSCR_RE
)) {
197 fprintf(stderr
, "serial port 1 not bound to anything\n");
200 serial1_update_parameters(s
);
202 if ((s
->scscr1
& SH7750_SCSCR_RE
) == 0) {
203 s
->scssr1
|= SH7750_SCSSR1_TDRE
;
207 static void init_serial1(SH7750State
* s
, int serial_nb
)
209 CharDriverState
*chr
;
212 chr
= serial_hds
[serial_nb
];
215 "no serial port associated to SH7750 first serial port\n");
220 qemu_chr_add_handlers(chr
, serial1_can_receive
,
221 serial1_receive
, serial1_event
, s
);
224 /**********************************************************************
226 **********************************************************************/
228 static int serial2_can_receive(void *opaque
)
230 SH7750State
*s
= opaque
;
231 static uint8_t max_fifo_size
[] = { 15, 1, 4, 6, 8, 10, 12, 14 };
233 return s
->serial2_receive_fifo
.length
<
234 max_fifo_size
[(s
->scfcr2
>> 9) & 7];
237 static void serial2_adjust_receive_flags(SH7750State
* s
)
239 static uint8_t max_fifo_size
[] = { 1, 4, 8, 14 };
241 /* XXXXX Add interrupt generation */
242 if (s
->serial2_receive_fifo
.length
>=
243 max_fifo_size
[(s
->scfcr2
>> 7) & 3]) {
244 s
->scfsr2
|= SH7750_SCFSR2_RDF
;
245 s
->scfsr2
&= ~SH7750_SCFSR2_DR
;
247 s
->scfsr2
&= ~SH7750_SCFSR2_RDF
;
248 if (s
->serial2_receive_fifo
.length
> 0)
249 s
->scfsr2
|= SH7750_SCFSR2_DR
;
251 s
->scfsr2
&= ~SH7750_SCFSR2_DR
;
255 static void serial2_append_char(SH7750State
* s
, uint8_t c
)
257 if (s
->serial2_receive_fifo
.length
== 16) {
259 s
->sclsr2
|= SH7750_SCLSR2_ORER
;
263 s
->serial2_receive_fifo
.data
[s
->serial2_receive_fifo
.write_idx
++] = c
;
264 s
->serial2_receive_fifo
.length
++;
265 serial2_adjust_receive_flags(s
);
268 static void serial2_receive(void *opaque
, const uint8_t * buf
, int size
)
270 SH7750State
*s
= opaque
;
273 for (i
= 0; i
< size
; i
++)
274 serial2_append_char(s
, buf
[i
]);
277 static void serial2_event(void *opaque
, int event
)
283 static void serial2_update_parameters(SH7750State
* s
)
285 QEMUSerialSetParams ssp
;
287 if (s
->scsmr2
& SH7750_SCSMR_CHR_7
)
291 if (s
->scsmr2
& SH7750_SCSMR_PE
) {
292 if (s
->scsmr2
& SH7750_SCSMR_PM_ODD
)
298 if (s
->scsmr2
& SH7750_SCSMR_STOP_2
)
302 fprintf(stderr
, "SCSMR2=%04x SCBRR2=%02x\n", s
->scsmr2
, s
->scbrr2
);
303 ssp
.speed
= s
->periph_freq
/
304 (32 * s
->scbrr2
* (1 << (2 * (s
->scsmr2
& 3)))) - 1;
305 fprintf(stderr
, "data bits=%d, stop bits=%d, parity=%c, speed=%d\n",
306 ssp
.data_bits
, ssp
.stop_bits
, ssp
.parity
, ssp
.speed
);
307 qemu_chr_ioctl(s
->serial2
, CHR_IOCTL_SERIAL_SET_PARAMS
, &ssp
);
310 static void scscr2_changed(SH7750State
* s
)
312 if (s
->scscr2
& (SH7750_SCSCR_TE
| SH7750_SCSCR_RE
)) {
314 fprintf(stderr
, "serial port 2 not bound to anything\n");
317 serial2_update_parameters(s
);
321 static void init_serial2(SH7750State
* s
, int serial_nb
)
323 CharDriverState
*chr
;
327 chr
= serial_hds
[serial_nb
];
330 "no serial port associated to SH7750 second serial port\n");
335 qemu_chr_add_handlers(chr
, serial2_can_receive
,
336 serial2_receive
, serial1_event
, s
);
339 static void init_serial_ports(SH7750State
* s
)
345 /**********************************************************************
347 **********************************************************************/
349 int sh7750_register_io_device(SH7750State
* s
, sh7750_io_device
* device
)
353 for (i
= 0; i
< NB_DEVICES
; i
++) {
354 if (s
->devices
[i
] == NULL
) {
355 s
->devices
[i
] = device
;
362 static uint16_t portdir(uint32_t v
)
364 #define EVENPORTMASK(n) ((v & (1<<((n)<<1))) >> (n))
366 EVENPORTMASK(15) | EVENPORTMASK(14) | EVENPORTMASK(13) |
367 EVENPORTMASK(12) | EVENPORTMASK(11) | EVENPORTMASK(10) |
368 EVENPORTMASK(9) | EVENPORTMASK(8) | EVENPORTMASK(7) |
369 EVENPORTMASK(6) | EVENPORTMASK(5) | EVENPORTMASK(4) |
370 EVENPORTMASK(3) | EVENPORTMASK(2) | EVENPORTMASK(1) |
374 static uint16_t portpullup(uint32_t v
)
376 #define ODDPORTMASK(n) ((v & (1<<(((n)<<1)+1))) >> (n))
378 ODDPORTMASK(15) | ODDPORTMASK(14) | ODDPORTMASK(13) |
379 ODDPORTMASK(12) | ODDPORTMASK(11) | ODDPORTMASK(10) |
380 ODDPORTMASK(9) | ODDPORTMASK(8) | ODDPORTMASK(7) | ODDPORTMASK(6) |
381 ODDPORTMASK(5) | ODDPORTMASK(4) | ODDPORTMASK(3) | ODDPORTMASK(2) |
382 ODDPORTMASK(1) | ODDPORTMASK(0);
385 static uint16_t porta_lines(SH7750State
* s
)
387 return (s
->portdira
& s
->pdtra
) | /* CPU */
388 (s
->periph_portdira
& s
->periph_pdtra
) | /* Peripherals */
389 (~(s
->portdira
| s
->periph_portdira
) & s
->portpullupa
); /* Pullups */
392 static uint16_t portb_lines(SH7750State
* s
)
394 return (s
->portdirb
& s
->pdtrb
) | /* CPU */
395 (s
->periph_portdirb
& s
->periph_pdtrb
) | /* Peripherals */
396 (~(s
->portdirb
| s
->periph_portdirb
) & s
->portpullupb
); /* Pullups */
399 static void gen_port_interrupts(SH7750State
* s
)
401 /* XXXXX interrupts not generated */
404 static void porta_changed(SH7750State
* s
, uint16_t prev
)
406 uint16_t currenta
, changes
;
410 fprintf(stderr
, "porta changed from 0x%04x to 0x%04x\n",
411 prev
, porta_lines(s
));
412 fprintf(stderr
, "pdtra=0x%04x, pctra=0x%08x\n", s
->pdtra
, s
->pctra
);
414 currenta
= porta_lines(s
);
415 if (currenta
== prev
)
417 changes
= currenta
^ prev
;
419 for (i
= 0; i
< NB_DEVICES
; i
++) {
420 if (s
->devices
[i
] && (s
->devices
[i
]->portamask_trigger
& changes
)) {
421 r
|= s
->devices
[i
]->port_change_cb(currenta
, portb_lines(s
),
425 &s
->periph_portdirb
);
430 gen_port_interrupts(s
);
433 static void portb_changed(SH7750State
* s
, uint16_t prev
)
435 uint16_t currentb
, changes
;
438 currentb
= portb_lines(s
);
439 if (currentb
== prev
)
441 changes
= currentb
^ prev
;
443 for (i
= 0; i
< NB_DEVICES
; i
++) {
444 if (s
->devices
[i
] && (s
->devices
[i
]->portbmask_trigger
& changes
)) {
445 r
|= s
->devices
[i
]->port_change_cb(portb_lines(s
), currentb
,
449 &s
->periph_portdirb
);
454 gen_port_interrupts(s
);
457 /**********************************************************************
459 **********************************************************************/
461 static void error_access(const char *kind
, target_phys_addr_t addr
)
463 fprintf(stderr
, "%s to %s (0x%08x) not supported\n",
464 kind
, regname(addr
), addr
);
467 static void ignore_access(const char *kind
, target_phys_addr_t addr
)
469 fprintf(stderr
, "%s to %s (0x%08x) ignored\n",
470 kind
, regname(addr
), addr
);
473 static uint32_t sh7750_mem_readb(void *opaque
, target_phys_addr_t addr
)
475 SH7750State
*s
= opaque
;
479 case SH7750_SCSSR1_A7
:
483 case SH7750_SCRDR1_A7
:
484 s
->scssr1
&= ~SH7750_SCSSR1_RDRF
;
487 error_access("byte read", addr
);
492 static uint32_t sh7750_mem_readw(void *opaque
, target_phys_addr_t addr
)
494 SH7750State
*s
= opaque
;
500 "Read access to refresh count register, incrementing\n");
502 case SH7750_SCLSR2_A7
:
503 /* Read and clear overflow bit */
507 case SH7750_SCSFR2_A7
:
509 case SH7750_PDTRA_A7
:
510 return porta_lines(s
);
511 case SH7750_PDTRB_A7
:
512 return portb_lines(s
);
514 error_access("word read", addr
);
519 static uint32_t sh7750_mem_readl(void *opaque
, target_phys_addr_t addr
)
521 SH7750State
*s
= opaque
;
524 case SH7750_MMUCR_A7
:
525 return s
->cpu
->mmucr
;
536 case SH7750_EXPEVT_A7
:
537 return s
->cpu
->expevt
;
538 case SH7750_INTEVT_A7
:
539 return s
->cpu
->intevt
;
542 case 0x1f000030: /* Processor version PVR */
543 return 0x00050000; /* SH7750R */
544 case 0x1f000040: /* Processor version CVR */
545 return 0x00110000; /* Minimum caches */
546 case 0x1f000044: /* Processor version PRR */
547 return 0x00000100; /* SH7750R */
549 error_access("long read", addr
);
554 static void sh7750_mem_writeb(void *opaque
, target_phys_addr_t addr
,
557 SH7750State
*s
= opaque
;
560 /* PRECHARGE ? XXXXX */
561 case SH7750_PRECHARGE0_A7
:
562 case SH7750_PRECHARGE1_A7
:
563 ignore_access("byte write", addr
);
565 case SH7750_SCBRR2_A7
:
566 s
->scbrr2
= mem_value
;
568 case SH7750_SCSCR1_A7
:
569 s
->scscr1
= mem_value
;
572 case SH7750_SCSMR1_A7
:
573 s
->scsmr1
= mem_value
;
575 case SH7750_SCBRR1_A7
:
576 s
->scbrr1
= mem_value
;
578 case SH7750_SCTDR1_A7
:
579 s
->scssr1
&= ~SH7750_SCSSR1_TEND
;
580 s
->sctdr1
= mem_value
;
582 case SH7750_SCSSR1_A7
:
583 serial1_change_scssr1(s
, mem_value
);
586 error_access("byte write", addr
);
591 static void sh7750_mem_writew(void *opaque
, target_phys_addr_t addr
,
594 SH7750State
*s
= opaque
;
598 /* SDRAM controller */
599 case SH7750_SCBRR1_A7
:
600 case SH7750_SCBRR2_A7
:
603 case SH7750_RTCOR_A7
:
604 case SH7750_RTCNT_A7
:
605 case SH7750_RTCSR_A7
:
606 ignore_access("word write", addr
);
609 case SH7750_PDTRA_A7
:
610 temp
= porta_lines(s
);
611 s
->pdtra
= mem_value
;
612 porta_changed(s
, temp
);
614 case SH7750_PDTRB_A7
:
615 temp
= portb_lines(s
);
616 s
->pdtrb
= mem_value
;
617 portb_changed(s
, temp
);
620 fprintf(stderr
, "Write access to refresh count register\n");
623 case SH7750_SCLSR2_A7
:
624 s
->sclsr2
= mem_value
;
626 case SH7750_SCSCR2_A7
:
627 s
->scscr2
= mem_value
;
630 case SH7750_SCFCR2_A7
:
631 s
->scfcr2
= mem_value
;
633 case SH7750_SCSMR2_A7
:
634 s
->scsmr2
= mem_value
;
636 case SH7750_GPIOIC_A7
:
637 s
->gpioic
= mem_value
;
638 if (mem_value
!= 0) {
639 fprintf(stderr
, "I/O interrupts not implemented\n");
644 error_access("word write", addr
);
649 static void sh7750_mem_writel(void *opaque
, target_phys_addr_t addr
,
652 SH7750State
*s
= opaque
;
656 /* SDRAM controller */
663 ignore_access("long write", addr
);
666 case SH7750_PCTRA_A7
:
667 temp
= porta_lines(s
);
668 s
->pctra
= mem_value
;
669 s
->portdira
= portdir(mem_value
);
670 s
->portpullupa
= portpullup(mem_value
);
671 porta_changed(s
, temp
);
673 case SH7750_PCTRB_A7
:
674 temp
= portb_lines(s
);
675 s
->pctrb
= mem_value
;
676 s
->portdirb
= portdir(mem_value
);
677 s
->portpullupb
= portpullup(mem_value
);
678 portb_changed(s
, temp
);
680 case SH7750_MMUCR_A7
:
681 s
->cpu
->mmucr
= mem_value
;
684 s
->cpu
->pteh
= mem_value
;
687 s
->cpu
->ptel
= mem_value
;
690 s
->cpu
->ttb
= mem_value
;
693 s
->cpu
->tea
= mem_value
;
696 s
->cpu
->tra
= mem_value
& 0x000007ff;
698 case SH7750_EXPEVT_A7
:
699 s
->cpu
->expevt
= mem_value
& 0x000007ff;
701 case SH7750_INTEVT_A7
:
702 s
->cpu
->intevt
= mem_value
& 0x000007ff;
708 error_access("long write", addr
);
713 static CPUReadMemoryFunc
*sh7750_mem_read
[] = {
719 static CPUWriteMemoryFunc
*sh7750_mem_write
[] = {
725 SH7750State
*sh7750_init(CPUSH4State
* cpu
)
728 int sh7750_io_memory
;
730 s
= qemu_mallocz(sizeof(SH7750State
));
732 s
->periph_freq
= 60000000; /* 60MHz */
733 sh7750_io_memory
= cpu_register_io_memory(0,
735 sh7750_mem_write
, s
);
736 cpu_register_physical_memory(0x1c000000, 0x04000000, sh7750_io_memory
);
737 init_serial_ports(s
);
739 tmu012_init(0x1fd80000,
740 TMU012_FEAT_TOCR
| TMU012_FEAT_3CHAN
| TMU012_FEAT_EXTCLK
,
742 tmu012_init(0x1e100000, 0, s
->periph_freq
);