Commit 2f062c72275938cc8fcbf0ce083b73a35d6a5329
1 parent
cd1a3f68
Stand-alone SCI/SCIF emulation code, by Magnus Damm.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3270 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
6 changed files
with
325 additions
and
585 deletions
Makefile.target
@@ -476,7 +476,7 @@ CPPFLAGS += -DHAS_AUDIO | @@ -476,7 +476,7 @@ CPPFLAGS += -DHAS_AUDIO | ||
476 | endif | 476 | endif |
477 | ifeq ($(TARGET_BASE_ARCH), sh4) | 477 | ifeq ($(TARGET_BASE_ARCH), sh4) |
478 | VL_OBJS+= shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o | 478 | VL_OBJS+= shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o |
479 | -VL_OBJS+= sh_timer.o ptimer.o | 479 | +VL_OBJS+= sh_timer.o ptimer.o sh_serial.o |
480 | endif | 480 | endif |
481 | ifeq ($(TARGET_BASE_ARCH), m68k) | 481 | ifeq ($(TARGET_BASE_ARCH), m68k) |
482 | VL_OBJS+= an5206.o mcf5206.o ptimer.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o | 482 | VL_OBJS+= an5206.o mcf5206.o ptimer.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o |
hw/sh7750.c
@@ -27,13 +27,6 @@ | @@ -27,13 +27,6 @@ | ||
27 | #include "sh7750_regs.h" | 27 | #include "sh7750_regs.h" |
28 | #include "sh7750_regnames.h" | 28 | #include "sh7750_regnames.h" |
29 | 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 | 30 | #define NB_DEVICES 4 |
38 | 31 | ||
39 | typedef struct SH7750State { | 32 | typedef struct SH7750State { |
@@ -43,27 +36,6 @@ typedef struct SH7750State { | @@ -43,27 +36,6 @@ typedef struct SH7750State { | ||
43 | uint32_t periph_freq; | 36 | uint32_t periph_freq; |
44 | /* SDRAM controller */ | 37 | /* SDRAM controller */ |
45 | uint16_t rfcr; | 38 | 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 | /* IO ports */ | 39 | /* IO ports */ |
68 | uint16_t gpioic; | 40 | uint16_t gpioic; |
69 | uint32_t pctra; | 41 | uint32_t pctra; |
@@ -84,263 +56,6 @@ typedef struct SH7750State { | @@ -84,263 +56,6 @@ typedef struct SH7750State { | ||
84 | 56 | ||
85 | } SH7750State; | 57 | } SH7750State; |
86 | 58 | ||
87 | -/********************************************************************** | ||
88 | - First serial port | ||
89 | -**********************************************************************/ | ||
90 | - | ||
91 | -static int serial1_can_receive(void *opaque) | ||
92 | -{ | ||
93 | - SH7750State *s = opaque; | ||
94 | - | ||
95 | - return s->scscr1 & SH7750_SCSCR_RE; | ||
96 | -} | ||
97 | - | ||
98 | -static void serial1_receive_char(SH7750State * s, uint8_t c) | ||
99 | -{ | ||
100 | - if (s->scssr1 & SH7750_SCSSR1_RDRF) { | ||
101 | - s->scssr1 |= SH7750_SCSSR1_ORER; | ||
102 | - return; | ||
103 | - } | ||
104 | - | ||
105 | - s->scrdr1 = c; | ||
106 | - s->scssr1 |= SH7750_SCSSR1_RDRF; | ||
107 | -} | ||
108 | - | ||
109 | -static void serial1_receive(void *opaque, const uint8_t * buf, int size) | ||
110 | -{ | ||
111 | - SH7750State *s = opaque; | ||
112 | - int i; | ||
113 | - | ||
114 | - for (i = 0; i < size; i++) { | ||
115 | - serial1_receive_char(s, buf[i]); | ||
116 | - } | ||
117 | -} | ||
118 | - | ||
119 | -static void serial1_event(void *opaque, int event) | ||
120 | -{ | ||
121 | - assert(0); | ||
122 | -} | ||
123 | - | ||
124 | -static void serial1_maybe_send(SH7750State * s) | ||
125 | -{ | ||
126 | - uint8_t c; | ||
127 | - | ||
128 | - if (s->scssr1 & SH7750_SCSSR1_TDRE) | ||
129 | - return; | ||
130 | - c = s->sctdr1; | ||
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"); | ||
134 | - assert(0); | ||
135 | - } | ||
136 | - /* XXXXX Check for errors in write */ | ||
137 | - qemu_chr_write(s->serial1, &c, 1); | ||
138 | -} | ||
139 | - | ||
140 | -static void serial1_change_scssr1(SH7750State * s, uint8_t mem_value) | ||
141 | -{ | ||
142 | - uint8_t new_flags; | ||
143 | - | ||
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; | ||
147 | - } | ||
148 | - | ||
149 | - /* Only clear bits which have been read before and do not set any bit | ||
150 | - in the flags */ | ||
151 | - new_flags = s->scssr1 & ~s->scssr1_read; /* Preserve unread flags */ | ||
152 | - new_flags &= mem_value | ~s->scssr1_read; /* Clear read flags */ | ||
153 | - | ||
154 | - s->scssr1 = (new_flags & 0xf8) | (mem_value & 1); | ||
155 | - s->scssr1_read &= mem_value; | ||
156 | - | ||
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; | ||
160 | - } | ||
161 | - | ||
162 | - /* Check for transmission to start */ | ||
163 | - serial1_maybe_send(s); | ||
164 | -} | ||
165 | - | ||
166 | -static void serial1_update_parameters(SH7750State * s) | ||
167 | -{ | ||
168 | - QEMUSerialSetParams ssp; | ||
169 | - | ||
170 | - if (s->scsmr1 & SH7750_SCSMR_CHR_7) | ||
171 | - ssp.data_bits = 7; | ||
172 | - else | ||
173 | - ssp.data_bits = 8; | ||
174 | - if (s->scsmr1 & SH7750_SCSMR_PE) { | ||
175 | - if (s->scsmr1 & SH7750_SCSMR_PM_ODD) | ||
176 | - ssp.parity = 'O'; | ||
177 | - else | ||
178 | - ssp.parity = 'E'; | ||
179 | - } else | ||
180 | - ssp.parity = 'N'; | ||
181 | - if (s->scsmr1 & SH7750_SCSMR_STOP_2) | ||
182 | - ssp.stop_bits = 2; | ||
183 | - else | ||
184 | - ssp.stop_bits = 1; | ||
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); | ||
191 | -} | ||
192 | - | ||
193 | -static void scscr1_changed(SH7750State * s) | ||
194 | -{ | ||
195 | - if (s->scscr1 & (SH7750_SCSCR_TE | SH7750_SCSCR_RE)) { | ||
196 | - if (!s->serial1) { | ||
197 | - fprintf(stderr, "serial port 1 not bound to anything\n"); | ||
198 | - assert(0); | ||
199 | - } | ||
200 | - serial1_update_parameters(s); | ||
201 | - } | ||
202 | - if ((s->scscr1 & SH7750_SCSCR_RE) == 0) { | ||
203 | - s->scssr1 |= SH7750_SCSSR1_TDRE; | ||
204 | - } | ||
205 | -} | ||
206 | - | ||
207 | -static void init_serial1(SH7750State * s, int serial_nb) | ||
208 | -{ | ||
209 | - CharDriverState *chr; | ||
210 | - | ||
211 | - s->scssr1 = 0x84; | ||
212 | - chr = serial_hds[serial_nb]; | ||
213 | - if (!chr) { | ||
214 | - fprintf(stderr, | ||
215 | - "no serial port associated to SH7750 first serial port\n"); | ||
216 | - return; | ||
217 | - } | ||
218 | - | ||
219 | - s->serial1 = chr; | ||
220 | - qemu_chr_add_handlers(chr, serial1_can_receive, | ||
221 | - serial1_receive, serial1_event, s); | ||
222 | -} | ||
223 | - | ||
224 | -/********************************************************************** | ||
225 | - Second serial port | ||
226 | -**********************************************************************/ | ||
227 | - | ||
228 | -static int serial2_can_receive(void *opaque) | ||
229 | -{ | ||
230 | - SH7750State *s = opaque; | ||
231 | - static uint8_t max_fifo_size[] = { 15, 1, 4, 6, 8, 10, 12, 14 }; | ||
232 | - | ||
233 | - return s->serial2_receive_fifo.length < | ||
234 | - max_fifo_size[(s->scfcr2 >> 9) & 7]; | ||
235 | -} | ||
236 | - | ||
237 | -static void serial2_adjust_receive_flags(SH7750State * s) | ||
238 | -{ | ||
239 | - static uint8_t max_fifo_size[] = { 1, 4, 8, 14 }; | ||
240 | - | ||
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; | ||
246 | - } else { | ||
247 | - s->scfsr2 &= ~SH7750_SCFSR2_RDF; | ||
248 | - if (s->serial2_receive_fifo.length > 0) | ||
249 | - s->scfsr2 |= SH7750_SCFSR2_DR; | ||
250 | - else | ||
251 | - s->scfsr2 &= ~SH7750_SCFSR2_DR; | ||
252 | - } | ||
253 | -} | ||
254 | - | ||
255 | -static void serial2_append_char(SH7750State * s, uint8_t c) | ||
256 | -{ | ||
257 | - if (s->serial2_receive_fifo.length == 16) { | ||
258 | - /* Overflow */ | ||
259 | - s->sclsr2 |= SH7750_SCLSR2_ORER; | ||
260 | - return; | ||
261 | - } | ||
262 | - | ||
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); | ||
266 | -} | ||
267 | - | ||
268 | -static void serial2_receive(void *opaque, const uint8_t * buf, int size) | ||
269 | -{ | ||
270 | - SH7750State *s = opaque; | ||
271 | - int i; | ||
272 | - | ||
273 | - for (i = 0; i < size; i++) | ||
274 | - serial2_append_char(s, buf[i]); | ||
275 | -} | ||
276 | - | ||
277 | -static void serial2_event(void *opaque, int event) | ||
278 | -{ | ||
279 | - /* XXXXX */ | ||
280 | - assert(0); | ||
281 | -} | ||
282 | - | ||
283 | -static void serial2_update_parameters(SH7750State * s) | ||
284 | -{ | ||
285 | - QEMUSerialSetParams ssp; | ||
286 | - | ||
287 | - if (s->scsmr2 & SH7750_SCSMR_CHR_7) | ||
288 | - ssp.data_bits = 7; | ||
289 | - else | ||
290 | - ssp.data_bits = 8; | ||
291 | - if (s->scsmr2 & SH7750_SCSMR_PE) { | ||
292 | - if (s->scsmr2 & SH7750_SCSMR_PM_ODD) | ||
293 | - ssp.parity = 'O'; | ||
294 | - else | ||
295 | - ssp.parity = 'E'; | ||
296 | - } else | ||
297 | - ssp.parity = 'N'; | ||
298 | - if (s->scsmr2 & SH7750_SCSMR_STOP_2) | ||
299 | - ssp.stop_bits = 2; | ||
300 | - else | ||
301 | - ssp.stop_bits = 1; | ||
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); | ||
308 | -} | ||
309 | - | ||
310 | -static void scscr2_changed(SH7750State * s) | ||
311 | -{ | ||
312 | - if (s->scscr2 & (SH7750_SCSCR_TE | SH7750_SCSCR_RE)) { | ||
313 | - if (!s->serial2) { | ||
314 | - fprintf(stderr, "serial port 2 not bound to anything\n"); | ||
315 | - assert(0); | ||
316 | - } | ||
317 | - serial2_update_parameters(s); | ||
318 | - } | ||
319 | -} | ||
320 | - | ||
321 | -static void init_serial2(SH7750State * s, int serial_nb) | ||
322 | -{ | ||
323 | - CharDriverState *chr; | ||
324 | - | ||
325 | - s->scfsr2 = 0x0060; | ||
326 | - | ||
327 | - chr = serial_hds[serial_nb]; | ||
328 | - if (!chr) { | ||
329 | - fprintf(stderr, | ||
330 | - "no serial port associated to SH7750 second serial port\n"); | ||
331 | - return; | ||
332 | - } | ||
333 | - | ||
334 | - s->serial2 = chr; | ||
335 | - qemu_chr_add_handlers(chr, serial2_can_receive, | ||
336 | - serial2_receive, serial1_event, s); | ||
337 | -} | ||
338 | - | ||
339 | -static void init_serial_ports(SH7750State * s) | ||
340 | -{ | ||
341 | - init_serial1(s, 0); | ||
342 | - init_serial2(s, 1); | ||
343 | -} | ||
344 | 59 | ||
345 | /********************************************************************** | 60 | /********************************************************************** |
346 | I/O ports | 61 | I/O ports |
@@ -472,17 +187,7 @@ static void ignore_access(const char *kind, target_phys_addr_t addr) | @@ -472,17 +187,7 @@ static void ignore_access(const char *kind, target_phys_addr_t addr) | ||
472 | 187 | ||
473 | static uint32_t sh7750_mem_readb(void *opaque, target_phys_addr_t addr) | 188 | static uint32_t sh7750_mem_readb(void *opaque, target_phys_addr_t addr) |
474 | { | 189 | { |
475 | - SH7750State *s = opaque; | ||
476 | - uint8_t r; | ||
477 | - | ||
478 | switch (addr) { | 190 | switch (addr) { |
479 | - case SH7750_SCSSR1_A7: | ||
480 | - r = s->scssr1; | ||
481 | - s->scssr1_read |= r; | ||
482 | - return s->scssr1; | ||
483 | - case SH7750_SCRDR1_A7: | ||
484 | - s->scssr1 &= ~SH7750_SCSSR1_RDRF; | ||
485 | - return s->scrdr1; | ||
486 | default: | 191 | default: |
487 | error_access("byte read", addr); | 192 | error_access("byte read", addr); |
488 | assert(0); | 193 | assert(0); |
@@ -492,20 +197,12 @@ static uint32_t sh7750_mem_readb(void *opaque, target_phys_addr_t addr) | @@ -492,20 +197,12 @@ static uint32_t sh7750_mem_readb(void *opaque, target_phys_addr_t addr) | ||
492 | static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr) | 197 | static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr) |
493 | { | 198 | { |
494 | SH7750State *s = opaque; | 199 | SH7750State *s = opaque; |
495 | - uint16_t r; | ||
496 | 200 | ||
497 | switch (addr) { | 201 | switch (addr) { |
498 | case SH7750_RFCR_A7: | 202 | case SH7750_RFCR_A7: |
499 | fprintf(stderr, | 203 | fprintf(stderr, |
500 | "Read access to refresh count register, incrementing\n"); | 204 | "Read access to refresh count register, incrementing\n"); |
501 | return s->rfcr++; | 205 | return s->rfcr++; |
502 | - case SH7750_SCLSR2_A7: | ||
503 | - /* Read and clear overflow bit */ | ||
504 | - r = s->sclsr2; | ||
505 | - s->sclsr2 = 0; | ||
506 | - return r; | ||
507 | - case SH7750_SCSFR2_A7: | ||
508 | - return s->scfsr2; | ||
509 | case SH7750_PDTRA_A7: | 206 | case SH7750_PDTRA_A7: |
510 | return porta_lines(s); | 207 | return porta_lines(s); |
511 | case SH7750_PDTRB_A7: | 208 | case SH7750_PDTRB_A7: |
@@ -554,34 +251,12 @@ static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr) | @@ -554,34 +251,12 @@ static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr) | ||
554 | static void sh7750_mem_writeb(void *opaque, target_phys_addr_t addr, | 251 | static void sh7750_mem_writeb(void *opaque, target_phys_addr_t addr, |
555 | uint32_t mem_value) | 252 | uint32_t mem_value) |
556 | { | 253 | { |
557 | - SH7750State *s = opaque; | ||
558 | - | ||
559 | switch (addr) { | 254 | switch (addr) { |
560 | /* PRECHARGE ? XXXXX */ | 255 | /* PRECHARGE ? XXXXX */ |
561 | case SH7750_PRECHARGE0_A7: | 256 | case SH7750_PRECHARGE0_A7: |
562 | case SH7750_PRECHARGE1_A7: | 257 | case SH7750_PRECHARGE1_A7: |
563 | ignore_access("byte write", addr); | 258 | ignore_access("byte write", addr); |
564 | return; | 259 | return; |
565 | - case SH7750_SCBRR2_A7: | ||
566 | - s->scbrr2 = mem_value; | ||
567 | - return; | ||
568 | - case SH7750_SCSCR1_A7: | ||
569 | - s->scscr1 = mem_value; | ||
570 | - scscr1_changed(s); | ||
571 | - return; | ||
572 | - case SH7750_SCSMR1_A7: | ||
573 | - s->scsmr1 = mem_value; | ||
574 | - return; | ||
575 | - case SH7750_SCBRR1_A7: | ||
576 | - s->scbrr1 = mem_value; | ||
577 | - return; | ||
578 | - case SH7750_SCTDR1_A7: | ||
579 | - s->scssr1 &= ~SH7750_SCSSR1_TEND; | ||
580 | - s->sctdr1 = mem_value; | ||
581 | - return; | ||
582 | - case SH7750_SCSSR1_A7: | ||
583 | - serial1_change_scssr1(s, mem_value); | ||
584 | - return; | ||
585 | default: | 260 | default: |
586 | error_access("byte write", addr); | 261 | error_access("byte write", addr); |
587 | assert(0); | 262 | assert(0); |
@@ -596,8 +271,6 @@ static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr, | @@ -596,8 +271,6 @@ static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr, | ||
596 | 271 | ||
597 | switch (addr) { | 272 | switch (addr) { |
598 | /* SDRAM controller */ | 273 | /* SDRAM controller */ |
599 | - case SH7750_SCBRR1_A7: | ||
600 | - case SH7750_SCBRR2_A7: | ||
601 | case SH7750_BCR2_A7: | 274 | case SH7750_BCR2_A7: |
602 | case SH7750_BCR3_A7: | 275 | case SH7750_BCR3_A7: |
603 | case SH7750_RTCOR_A7: | 276 | case SH7750_RTCOR_A7: |
@@ -620,19 +293,6 @@ static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr, | @@ -620,19 +293,6 @@ static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr, | ||
620 | fprintf(stderr, "Write access to refresh count register\n"); | 293 | fprintf(stderr, "Write access to refresh count register\n"); |
621 | s->rfcr = mem_value; | 294 | s->rfcr = mem_value; |
622 | return; | 295 | return; |
623 | - case SH7750_SCLSR2_A7: | ||
624 | - s->sclsr2 = mem_value; | ||
625 | - return; | ||
626 | - case SH7750_SCSCR2_A7: | ||
627 | - s->scscr2 = mem_value; | ||
628 | - scscr2_changed(s); | ||
629 | - return; | ||
630 | - case SH7750_SCFCR2_A7: | ||
631 | - s->scfcr2 = mem_value; | ||
632 | - return; | ||
633 | - case SH7750_SCSMR2_A7: | ||
634 | - s->scsmr2 = mem_value; | ||
635 | - return; | ||
636 | case SH7750_GPIOIC_A7: | 296 | case SH7750_GPIOIC_A7: |
637 | s->gpioic = mem_value; | 297 | s->gpioic = mem_value; |
638 | if (mem_value != 0) { | 298 | if (mem_value != 0) { |
@@ -734,7 +394,10 @@ SH7750State *sh7750_init(CPUSH4State * cpu) | @@ -734,7 +394,10 @@ SH7750State *sh7750_init(CPUSH4State * cpu) | ||
734 | sh7750_mem_read, | 394 | sh7750_mem_read, |
735 | sh7750_mem_write, s); | 395 | sh7750_mem_write, s); |
736 | cpu_register_physical_memory(0x1c000000, 0x04000000, sh7750_io_memory); | 396 | cpu_register_physical_memory(0x1c000000, 0x04000000, sh7750_io_memory); |
737 | - init_serial_ports(s); | 397 | + |
398 | + sh_serial_init(0x1fe00000, 0, s->periph_freq, serial_hds[0]); | ||
399 | + sh_serial_init(0x1fe80000, SH_SERIAL_FEAT_SCIF, | ||
400 | + s->periph_freq, serial_hds[1]); | ||
738 | 401 | ||
739 | tmu012_init(0x1fd80000, | 402 | tmu012_init(0x1fd80000, |
740 | TMU012_FEAT_TOCR | TMU012_FEAT_3CHAN | TMU012_FEAT_EXTCLK, | 403 | TMU012_FEAT_TOCR | TMU012_FEAT_3CHAN | TMU012_FEAT_EXTCLK, |
hw/sh7750_regnames.c
@@ -70,24 +70,6 @@ static regname_t regnames[] = { | @@ -70,24 +70,6 @@ static regname_t regnames[] = { | ||
70 | REGNAME(SH7750_CHCR2_A7) | 70 | REGNAME(SH7750_CHCR2_A7) |
71 | REGNAME(SH7750_CHCR3_A7) | 71 | REGNAME(SH7750_CHCR3_A7) |
72 | REGNAME(SH7750_DMAOR_A7) | 72 | REGNAME(SH7750_DMAOR_A7) |
73 | - REGNAME(SH7750_SCRDR1_A7) | ||
74 | - REGNAME(SH7750_SCRDR2_A7) | ||
75 | - REGNAME(SH7750_SCTDR1_A7) | ||
76 | - REGNAME(SH7750_SCTDR2_A7) | ||
77 | - REGNAME(SH7750_SCSMR1_A7) | ||
78 | - REGNAME(SH7750_SCSMR2_A7) | ||
79 | - REGNAME(SH7750_SCSCR1_A7) | ||
80 | - REGNAME(SH7750_SCSCR2_A7) | ||
81 | - REGNAME(SH7750_SCSSR1_A7) | ||
82 | - REGNAME(SH7750_SCSFR2_A7) | ||
83 | - REGNAME(SH7750_SCSPTR1_A7) | ||
84 | - REGNAME(SH7750_SCSPTR2_A7) | ||
85 | - REGNAME(SH7750_SCBRR1_A7) | ||
86 | - REGNAME(SH7750_SCBRR2_A7) | ||
87 | - REGNAME(SH7750_SCFCR2_A7) | ||
88 | - REGNAME(SH7750_SCFDR2_A7) | ||
89 | - REGNAME(SH7750_SCLSR2_A7) | ||
90 | - REGNAME(SH7750_SCSCMR1_A7) | ||
91 | REGNAME(SH7750_PCTRA_A7) | 73 | REGNAME(SH7750_PCTRA_A7) |
92 | REGNAME(SH7750_PDTRA_A7) | 74 | REGNAME(SH7750_PDTRA_A7) |
93 | REGNAME(SH7750_PCTRB_A7) | 75 | REGNAME(SH7750_PCTRB_A7) |
hw/sh7750_regs.h
@@ -1169,231 +1169,6 @@ | @@ -1169,231 +1169,6 @@ | ||
1169 | #define SH7750_DMAOR_DME 0x00000001 /* DMAC Master Enable */ | 1169 | #define SH7750_DMAOR_DME 0x00000001 /* DMAC Master Enable */ |
1170 | 1170 | ||
1171 | /* | 1171 | /* |
1172 | - * Serial Communication Interface - SCI | ||
1173 | - * Serial Communication Interface with FIFO - SCIF | ||
1174 | - */ | ||
1175 | -/* SCI Receive Data Register (byte, read-only) - SCRDR1, SCFRDR2 */ | ||
1176 | -#define SH7750_SCRDR_REGOFS(n) ((n) == 1 ? 0xE00014 : 0xE80014) /* offset */ | ||
1177 | -#define SH7750_SCRDR(n) SH7750_P4_REG32(SH7750_SCRDR_REGOFS(n)) | ||
1178 | -#define SH7750_SCRDR1 SH7750_SCRDR(1) | ||
1179 | -#define SH7750_SCRDR2 SH7750_SCRDR(2) | ||
1180 | -#define SH7750_SCRDR_A7(n) SH7750_A7_REG32(SH7750_SCRDR_REGOFS(n)) | ||
1181 | -#define SH7750_SCRDR1_A7 SH7750_SCRDR_A7(1) | ||
1182 | -#define SH7750_SCRDR2_A7 SH7750_SCRDR_A7(2) | ||
1183 | - | ||
1184 | -/* SCI Transmit Data Register (byte) - SCTDR1, SCFTDR2 */ | ||
1185 | -#define SH7750_SCTDR_REGOFS(n) ((n) == 1 ? 0xE0000C : 0xE8000C) /* offset */ | ||
1186 | -#define SH7750_SCTDR(n) SH7750_P4_REG32(SH7750_SCTDR_REGOFS(n)) | ||
1187 | -#define SH7750_SCTDR1 SH7750_SCTDR(1) | ||
1188 | -#define SH7750_SCTDR2 SH7750_SCTDR(2) | ||
1189 | -#define SH7750_SCTDR_A7(n) SH7750_A7_REG32(SH7750_SCTDR_REGOFS(n)) | ||
1190 | -#define SH7750_SCTDR1_A7 SH7750_SCTDR_A7(1) | ||
1191 | -#define SH7750_SCTDR2_A7 SH7750_SCTDR_A7(2) | ||
1192 | - | ||
1193 | -/* SCI Serial Mode Register - SCSMR1(byte), SCSMR2(half) */ | ||
1194 | -#define SH7750_SCSMR_REGOFS(n) ((n) == 1 ? 0xE00000 : 0xE80000) /* offset */ | ||
1195 | -#define SH7750_SCSMR(n) SH7750_P4_REG32(SH7750_SCSMR_REGOFS(n)) | ||
1196 | -#define SH7750_SCSMR1 SH7750_SCSMR(1) | ||
1197 | -#define SH7750_SCSMR2 SH7750_SCSMR(2) | ||
1198 | -#define SH7750_SCSMR_A7(n) SH7750_A7_REG32(SH7750_SCSMR_REGOFS(n)) | ||
1199 | -#define SH7750_SCSMR1_A7 SH7750_SCSMR_A7(1) | ||
1200 | -#define SH7750_SCSMR2_A7 SH7750_SCSMR_A7(2) | ||
1201 | - | ||
1202 | -#define SH7750_SCSMR1_CA 0x80 /* Communication Mode (C/A\): */ | ||
1203 | -#define SH7750_SCSMR1_CA_ASYNC 0x00 /* Asynchronous Mode */ | ||
1204 | -#define SH7750_SCSMR1_CA_SYNC 0x80 /* Synchronous Mode */ | ||
1205 | -#define SH7750_SCSMR_CHR 0x40 /* Character Length: */ | ||
1206 | -#define SH7750_SCSMR_CHR_8 0x00 /* 8-bit data */ | ||
1207 | -#define SH7750_SCSMR_CHR_7 0x40 /* 7-bit data */ | ||
1208 | -#define SH7750_SCSMR_PE 0x20 /* Parity Enable */ | ||
1209 | -#define SH7750_SCSMR_PM 0x10 /* Parity Mode: */ | ||
1210 | -#define SH7750_SCSMR_PM_EVEN 0x00 /* Even Parity */ | ||
1211 | -#define SH7750_SCSMR_PM_ODD 0x10 /* Odd Parity */ | ||
1212 | -#define SH7750_SCSMR_STOP 0x08 /* Stop Bit Length: */ | ||
1213 | -#define SH7750_SCSMR_STOP_1 0x00 /* 1 stop bit */ | ||
1214 | -#define SH7750_SCSMR_STOP_2 0x08 /* 2 stop bit */ | ||
1215 | -#define SH7750_SCSMR1_MP 0x04 /* Multiprocessor Mode */ | ||
1216 | -#define SH7750_SCSMR_CKS 0x03 /* Clock Select */ | ||
1217 | -#define SH7750_SCSMR_CKS_S 0 | ||
1218 | -#define SH7750_SCSMR_CKS_DIV1 0x00 /* Periph clock */ | ||
1219 | -#define SH7750_SCSMR_CKS_DIV4 0x01 /* Periph clock / 4 */ | ||
1220 | -#define SH7750_SCSMR_CKS_DIV16 0x02 /* Periph clock / 16 */ | ||
1221 | -#define SH7750_SCSMR_CKS_DIV64 0x03 /* Periph clock / 64 */ | ||
1222 | - | ||
1223 | -/* SCI Serial Control Register - SCSCR1(byte), SCSCR2(half) */ | ||
1224 | -#define SH7750_SCSCR_REGOFS(n) ((n) == 1 ? 0xE00008 : 0xE80008) /* offset */ | ||
1225 | -#define SH7750_SCSCR(n) SH7750_P4_REG32(SH7750_SCSCR_REGOFS(n)) | ||
1226 | -#define SH7750_SCSCR1 SH7750_SCSCR(1) | ||
1227 | -#define SH7750_SCSCR2 SH7750_SCSCR(2) | ||
1228 | -#define SH7750_SCSCR_A7(n) SH7750_A7_REG32(SH7750_SCSCR_REGOFS(n)) | ||
1229 | -#define SH7750_SCSCR1_A7 SH7750_SCSCR_A7(1) | ||
1230 | -#define SH7750_SCSCR2_A7 SH7750_SCSCR_A7(2) | ||
1231 | - | ||
1232 | -#define SH7750_SCSCR_TIE 0x80 /* Transmit Interrupt Enable */ | ||
1233 | -#define SH7750_SCSCR_RIE 0x40 /* Receive Interrupt Enable */ | ||
1234 | -#define SH7750_SCSCR_TE 0x20 /* Transmit Enable */ | ||
1235 | -#define SH7750_SCSCR_RE 0x10 /* Receive Enable */ | ||
1236 | -#define SH7750_SCSCR1_MPIE 0x08 /* Multiprocessor Interrupt Enable */ | ||
1237 | -#define SH7750_SCSCR2_REIE 0x08 /* Receive Error Interrupt Enable */ | ||
1238 | -#define SH7750_SCSCR1_TEIE 0x04 /* Transmit End Interrupt Enable */ | ||
1239 | -#define SH7750_SCSCR1_CKE 0x03 /* Clock Enable: */ | ||
1240 | -#define SH7750_SCSCR_CKE_INTCLK 0x00 /* Use Internal Clock */ | ||
1241 | -#define SH7750_SCSCR_CKE_EXTCLK 0x02 /* Use External Clock from SCK */ | ||
1242 | -#define SH7750_SCSCR1_CKE_ASYNC_SCK_CLKOUT 0x01 /* Use SCK as a clock output | ||
1243 | - in asynchronous mode */ | ||
1244 | - | ||
1245 | -/* SCI Serial Status Register - SCSSR1(byte), SCSFR2(half) */ | ||
1246 | -#define SH7750_SCSSR_REGOFS(n) ((n) == 1 ? 0xE00010 : 0xE80010) /* offset */ | ||
1247 | -#define SH7750_SCSSR(n) SH7750_P4_REG32(SH7750_SCSSR_REGOFS(n)) | ||
1248 | -#define SH7750_SCSSR1 SH7750_SCSSR(1) | ||
1249 | -#define SH7750_SCSFR2 SH7750_SCSSR(2) | ||
1250 | -#define SH7750_SCSSR_A7(n) SH7750_A7_REG32(SH7750_SCSSR_REGOFS(n)) | ||
1251 | -#define SH7750_SCSSR1_A7 SH7750_SCSSR_A7(1) | ||
1252 | -#define SH7750_SCSFR2_A7 SH7750_SCSSR_A7(2) | ||
1253 | - | ||
1254 | -#define SH7750_SCSSR1_TDRE 0x80 /* Transmit Data Register Empty */ | ||
1255 | -#define SH7750_SCSSR1_RDRF 0x40 /* Receive Data Register Full */ | ||
1256 | -#define SH7750_SCSSR1_ORER 0x20 /* Overrun Error */ | ||
1257 | -#define SH7750_SCSSR1_FER 0x10 /* Framing Error */ | ||
1258 | -#define SH7750_SCSSR1_PER 0x08 /* Parity Error */ | ||
1259 | -#define SH7750_SCSSR1_TEND 0x04 /* Transmit End */ | ||
1260 | -#define SH7750_SCSSR1_MPB 0x02 /* Multiprocessor Bit */ | ||
1261 | -#define SH7750_SCSSR1_MPBT 0x01 /* Multiprocessor Bit Transfer */ | ||
1262 | - | ||
1263 | -#define SH7750_SCFSR2_PERN 0xF000 /* Number of Parity Errors */ | ||
1264 | -#define SH7750_SCFSR2_PERN_S 12 | ||
1265 | -#define SH7750_SCFSR2_FERN 0x0F00 /* Number of Framing Errors */ | ||
1266 | -#define SH7750_SCFSR2_FERN_S 8 | ||
1267 | -#define SH7750_SCFSR2_ER 0x0080 /* Receive Error */ | ||
1268 | -#define SH7750_SCFSR2_TEND 0x0040 /* Transmit End */ | ||
1269 | -#define SH7750_SCFSR2_TDFE 0x0020 /* Transmit FIFO Data Empty */ | ||
1270 | -#define SH7750_SCFSR2_BRK 0x0010 /* Break Detect */ | ||
1271 | -#define SH7750_SCFSR2_FER 0x0008 /* Framing Error */ | ||
1272 | -#define SH7750_SCFSR2_PER 0x0004 /* Parity Error */ | ||
1273 | -#define SH7750_SCFSR2_RDF 0x0002 /* Receive FIFO Data Full */ | ||
1274 | -#define SH7750_SCFSR2_DR 0x0001 /* Receive Data Ready */ | ||
1275 | - | ||
1276 | -/* SCI Serial Port Register - SCSPTR1(byte) */ | ||
1277 | -#define SH7750_SCSPTR1_REGOFS 0xE0001C /* offset */ | ||
1278 | -#define SH7750_SCSPTR1 SH7750_P4_REG32(SH7750_SCSPTR1_REGOFS) | ||
1279 | -#define SH7750_SCSPTR1_A7 SH7750_A7_REG32(SH7750_SCSPTR1_REGOFS) | ||
1280 | - | ||
1281 | -#define SH7750_SCSPTR1_EIO 0x80 /* Error Interrupt Only */ | ||
1282 | -#define SH7750_SCSPTR1_SPB1IO 0x08 /* 1: Output SPB1DT bit to SCK pin */ | ||
1283 | -#define SH7750_SCSPTR1_SPB1DT 0x04 /* Serial Port Clock Port Data */ | ||
1284 | -#define SH7750_SCSPTR1_SPB0IO 0x02 /* 1: Output SPB0DT bit to TxD pin */ | ||
1285 | -#define SH7750_SCSPTR1_SPB0DT 0x01 /* Serial Port Break Data */ | ||
1286 | - | ||
1287 | -/* SCIF Serial Port Register - SCSPTR2(half) */ | ||
1288 | -#define SH7750_SCSPTR2_REGOFS 0xE80020 /* offset */ | ||
1289 | -#define SH7750_SCSPTR2 SH7750_P4_REG32(SH7750_SCSPTR2_REGOFS) | ||
1290 | -#define SH7750_SCSPTR2_A7 SH7750_A7_REG32(SH7750_SCSPTR2_REGOFS) | ||
1291 | - | ||
1292 | -#define SH7750_SCSPTR2_RTSIO 0x80 /* 1: Output RTSDT bit to RTS2\ pin */ | ||
1293 | -#define SH7750_SCSPTR2_RTSDT 0x40 /* RTS Port Data */ | ||
1294 | -#define SH7750_SCSPTR2_CTSIO 0x20 /* 1: Output CTSDT bit to CTS2\ pin */ | ||
1295 | -#define SH7750_SCSPTR2_CTSDT 0x10 /* CTS Port Data */ | ||
1296 | -#define SH7750_SCSPTR2_SPB2IO 0x02 /* 1: Output SPBDT bit to TxD2 pin */ | ||
1297 | -#define SH7750_SCSPTR2_SPB2DT 0x01 /* Serial Port Break Data */ | ||
1298 | - | ||
1299 | -/* SCI Bit Rate Register - SCBRR1(byte), SCBRR2(byte) */ | ||
1300 | -#define SH7750_SCBRR_REGOFS(n) ((n) == 1 ? 0xE00004 : 0xE80004) /* offset */ | ||
1301 | -#define SH7750_SCBRR(n) SH7750_P4_REG32(SH7750_SCBRR_REGOFS(n)) | ||
1302 | -#define SH7750_SCBRR1 SH7750_SCBRR_P4(1) | ||
1303 | -#define SH7750_SCBRR2 SH7750_SCBRR_P4(2) | ||
1304 | -#define SH7750_SCBRR_A7(n) SH7750_A7_REG32(SH7750_SCBRR_REGOFS(n)) | ||
1305 | -#define SH7750_SCBRR1_A7 SH7750_SCBRR_A7(1) | ||
1306 | -#define SH7750_SCBRR2_A7 SH7750_SCBRR_A7(2) | ||
1307 | - | ||
1308 | -/* SCIF FIFO Control Register - SCFCR2(half) */ | ||
1309 | -#define SH7750_SCFCR2_REGOFS 0xE80018 /* offset */ | ||
1310 | -#define SH7750_SCFCR2 SH7750_P4_REG32(SH7750_SCFCR2_REGOFS) | ||
1311 | -#define SH7750_SCFCR2_A7 SH7750_A7_REG32(SH7750_SCFCR2_REGOFS) | ||
1312 | - | ||
1313 | -#define SH7750_SCFCR2_RSTRG 0x700 /* RTS2\ Output Active Trigger; RTS2\ | ||
1314 | - signal goes to high level when the | ||
1315 | - number of received data stored in | ||
1316 | - FIFO exceeds the trigger number */ | ||
1317 | -#define SH7750_SCFCR2_RSTRG_15 0x000 /* 15 bytes */ | ||
1318 | -#define SH7750_SCFCR2_RSTRG_1 0x000 /* 1 byte */ | ||
1319 | -#define SH7750_SCFCR2_RSTRG_4 0x000 /* 4 bytes */ | ||
1320 | -#define SH7750_SCFCR2_RSTRG_6 0x000 /* 6 bytes */ | ||
1321 | -#define SH7750_SCFCR2_RSTRG_8 0x000 /* 8 bytes */ | ||
1322 | -#define SH7750_SCFCR2_RSTRG_10 0x000 /* 10 bytes */ | ||
1323 | -#define SH7750_SCFCR2_RSTRG_14 0x000 /* 14 bytes */ | ||
1324 | - | ||
1325 | -#define SH7750_SCFCR2_RTRG 0x0C0 /* Receive FIFO Data Number Trigger, | ||
1326 | - Receive Data Full (RDF) Flag sets | ||
1327 | - when number of receive data bytes is | ||
1328 | - equal or greater than the trigger | ||
1329 | - number */ | ||
1330 | -#define SH7750_SCFCR2_RTRG_1 0x000 /* 1 byte */ | ||
1331 | -#define SH7750_SCFCR2_RTRG_4 0x040 /* 4 bytes */ | ||
1332 | -#define SH7750_SCFCR2_RTRG_8 0x080 /* 8 bytes */ | ||
1333 | -#define SH7750_SCFCR2_RTRG_14 0x0C0 /* 14 bytes */ | ||
1334 | - | ||
1335 | -#define SH7750_SCFCR2_TTRG 0x030 /* Transmit FIFO Data Number Trigger, | ||
1336 | - Transmit FIFO Data Register Empty (TDFE) | ||
1337 | - flag sets when the number of remaining | ||
1338 | - transmit data bytes is equal or less | ||
1339 | - than the trigger number */ | ||
1340 | -#define SH7750_SCFCR2_TTRG_8 0x000 /* 8 bytes */ | ||
1341 | -#define SH7750_SCFCR2_TTRG_4 0x010 /* 4 bytes */ | ||
1342 | -#define SH7750_SCFCR2_TTRG_2 0x020 /* 2 bytes */ | ||
1343 | -#define SH7750_SCFCR2_TTRG_1 0x030 /* 1 byte */ | ||
1344 | - | ||
1345 | -#define SH7750_SCFCR2_MCE 0x008 /* Modem Control Enable */ | ||
1346 | -#define SH7750_SCFCR2_TFRST 0x004 /* Transmit FIFO Data Register Reset, | ||
1347 | - invalidates the transmit data in the | ||
1348 | - transmit FIFO */ | ||
1349 | -#define SH7750_SCFCR2_RFRST 0x002 /* Receive FIFO Data Register Reset, | ||
1350 | - invalidates the receive data in the | ||
1351 | - receive FIFO data register and resets | ||
1352 | - it to the empty state */ | ||
1353 | -#define SH7750_SCFCR2_LOOP 0x001 /* Loopback Test */ | ||
1354 | - | ||
1355 | -/* SCIF FIFO Data Count Register - SCFDR2(half, read-only) */ | ||
1356 | -#define SH7750_SCFDR2_REGOFS 0xE8001C /* offset */ | ||
1357 | -#define SH7750_SCFDR2 SH7750_P4_REG32(SH7750_SCFDR2_REGOFS) | ||
1358 | -#define SH7750_SCFDR2_A7 SH7750_A7_REG32(SH7750_SCFDR2_REGOFS) | ||
1359 | - | ||
1360 | -#define SH7750_SCFDR2_T 0x1F00 /* Number of untransmitted data bytes | ||
1361 | - in transmit FIFO */ | ||
1362 | -#define SH7750_SCFDR2_T_S 8 | ||
1363 | -#define SH7750_SCFDR2_R 0x001F /* Number of received data bytes in | ||
1364 | - receive FIFO */ | ||
1365 | -#define SH7750_SCFDR2_R_S 0 | ||
1366 | - | ||
1367 | -/* SCIF Line Status Register - SCLSR2(half, read-only) */ | ||
1368 | -#define SH7750_SCLSR2_REGOFS 0xE80024 /* offset */ | ||
1369 | -#define SH7750_SCLSR2 SH7750_P4_REG32(SH7750_SCLSR2_REGOFS) | ||
1370 | -#define SH7750_SCLSR2_A7 SH7750_A7_REG32(SH7750_SCLSR2_REGOFS) | ||
1371 | - | ||
1372 | -#define SH7750_SCLSR2_ORER 0x0001 /* Overrun Error */ | ||
1373 | - | ||
1374 | -/* | ||
1375 | - * SCI-based Smart Card Interface | ||
1376 | - */ | ||
1377 | -/* Smart Card Mode Register - SCSCMR1(byte) */ | ||
1378 | -#define SH7750_SCSCMR1_REGOFS 0xE00018 /* offset */ | ||
1379 | -#define SH7750_SCSCMR1 SH7750_P4_REG32(SH7750_SCSCMR1_REGOFS) | ||
1380 | -#define SH7750_SCSCMR1_A7 SH7750_A7_REG32(SH7750_SCSCMR1_REGOFS) | ||
1381 | - | ||
1382 | -#define SH7750_SCSCMR1_SDIR 0x08 /* Smart Card Data Transfer Direction: */ | ||
1383 | -#define SH7750_SCSCMR1_SDIR_LSBF 0x00 /* LSB-first */ | ||
1384 | -#define SH7750_SCSCMR1_SDIR_MSBF 0x08 /* MSB-first */ | ||
1385 | - | ||
1386 | -#define SH7750_SCSCMR1_SINV 0x04 /* Smart Card Data Inversion */ | ||
1387 | -#define SH7750_SCSCMR1_SMIF 0x01 /* Smart Card Interface Mode Select */ | ||
1388 | - | ||
1389 | -/* Smart-card specific bits in other registers */ | ||
1390 | -/* SCSMR1: */ | ||
1391 | -#define SH7750_SCSMR1_GSM 0x80 /* GSM mode select */ | ||
1392 | - | ||
1393 | -/* SCSSR1: */ | ||
1394 | -#define SH7750_SCSSR1_ERS 0x10 /* Error Signal Status */ | ||
1395 | - | ||
1396 | -/* | ||
1397 | * I/O Ports | 1172 | * I/O Ports |
1398 | */ | 1173 | */ |
1399 | /* Port Control Register A - PCTRA */ | 1174 | /* Port Control Register A - PCTRA */ |
hw/sh_serial.c
0 โ 100644
1 | +/* | ||
2 | + * QEMU SCI/SCIF serial port emulation | ||
3 | + * | ||
4 | + * Copyright (c) 2007 Magnus Damm | ||
5 | + * | ||
6 | + * Based on serial.c - QEMU 16450 UART emulation | ||
7 | + * Copyright (c) 2003-2004 Fabrice Bellard | ||
8 | + * | ||
9 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
10 | + * of this software and associated documentation files (the "Software"), to deal | ||
11 | + * in the Software without restriction, including without limitation the rights | ||
12 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
13 | + * copies of the Software, and to permit persons to whom the Software is | ||
14 | + * furnished to do so, subject to the following conditions: | ||
15 | + * | ||
16 | + * The above copyright notice and this permission notice shall be included in | ||
17 | + * all copies or substantial portions of the Software. | ||
18 | + * | ||
19 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
20 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
21 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
22 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
23 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
24 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
25 | + * THE SOFTWARE. | ||
26 | + */ | ||
27 | +#include "vl.h" | ||
28 | +#include <assert.h> | ||
29 | + | ||
30 | +//#define DEBUG_SERIAL | ||
31 | + | ||
32 | +#define SH_SERIAL_FLAG_TEND (1 << 0) | ||
33 | +#define SH_SERIAL_FLAG_TDE (1 << 1) | ||
34 | +#define SH_SERIAL_FLAG_RDF (1 << 2) | ||
35 | +#define SH_SERIAL_FLAG_BRK (1 << 3) | ||
36 | +#define SH_SERIAL_FLAG_DR (1 << 4) | ||
37 | + | ||
38 | +typedef struct { | ||
39 | + uint8_t smr; | ||
40 | + uint8_t brr; | ||
41 | + uint8_t scr; | ||
42 | + uint8_t dr; /* ftdr / tdr */ | ||
43 | + uint8_t sr; /* fsr / ssr */ | ||
44 | + uint16_t fcr; | ||
45 | + uint8_t sptr; | ||
46 | + | ||
47 | + uint8_t rx_fifo[16]; /* frdr / rdr */ | ||
48 | + uint8_t rx_cnt; | ||
49 | + | ||
50 | + target_phys_addr_t base; | ||
51 | + int freq; | ||
52 | + int feat; | ||
53 | + int flags; | ||
54 | + | ||
55 | + CharDriverState *chr; | ||
56 | +} sh_serial_state; | ||
57 | + | ||
58 | +static void sh_serial_ioport_write(void *opaque, uint32_t offs, uint32_t val) | ||
59 | +{ | ||
60 | + sh_serial_state *s = opaque; | ||
61 | + unsigned char ch; | ||
62 | + | ||
63 | +#ifdef DEBUG_SERIAL | ||
64 | + printf("sh_serial: write base=0x%08lx offs=0x%02x val=0x%02x\n", | ||
65 | + (unsigned long) s->base, offs, val); | ||
66 | +#endif | ||
67 | + switch(offs) { | ||
68 | + case 0x00: /* SMR */ | ||
69 | + s->smr = val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0x7b : 0xff); | ||
70 | + return; | ||
71 | + case 0x04: /* BRR */ | ||
72 | + s->brr = val; | ||
73 | + return; | ||
74 | + case 0x08: /* SCR */ | ||
75 | + s->scr = val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0xfb : 0xff); | ||
76 | + if (!(val & (1 << 5))) | ||
77 | + s->flags |= SH_SERIAL_FLAG_TEND; | ||
78 | + return; | ||
79 | + case 0x0c: /* FTDR / TDR */ | ||
80 | + if (s->chr) { | ||
81 | + ch = val; | ||
82 | + qemu_chr_write(s->chr, &ch, 1); | ||
83 | + } | ||
84 | + s->dr = val; | ||
85 | + s->flags &= ~SH_SERIAL_FLAG_TDE; | ||
86 | + return; | ||
87 | +#if 0 | ||
88 | + case 0x14: /* FRDR / RDR */ | ||
89 | + ret = 0; | ||
90 | + break; | ||
91 | +#endif | ||
92 | + } | ||
93 | + if (s->feat & SH_SERIAL_FEAT_SCIF) { | ||
94 | + switch(offs) { | ||
95 | + case 0x10: /* FSR */ | ||
96 | + if (!(val & (1 << 6))) | ||
97 | + s->flags &= ~SH_SERIAL_FLAG_TEND; | ||
98 | + if (!(val & (1 << 5))) | ||
99 | + s->flags &= ~SH_SERIAL_FLAG_TDE; | ||
100 | + if (!(val & (1 << 4))) | ||
101 | + s->flags &= ~SH_SERIAL_FLAG_BRK; | ||
102 | + if (!(val & (1 << 1))) | ||
103 | + s->flags &= ~SH_SERIAL_FLAG_RDF; | ||
104 | + if (!(val & (1 << 0))) | ||
105 | + s->flags &= ~SH_SERIAL_FLAG_DR; | ||
106 | + return; | ||
107 | + case 0x18: /* FCR */ | ||
108 | + s->fcr = val; | ||
109 | + return; | ||
110 | + case 0x20: /* SPTR */ | ||
111 | + s->sptr = val; | ||
112 | + return; | ||
113 | + case 0x24: /* LSR */ | ||
114 | + return; | ||
115 | + } | ||
116 | + } | ||
117 | + else { | ||
118 | +#if 0 | ||
119 | + switch(offs) { | ||
120 | + case 0x0c: | ||
121 | + ret = s->dr; | ||
122 | + break; | ||
123 | + case 0x10: | ||
124 | + ret = 0; | ||
125 | + break; | ||
126 | + case 0x1c: | ||
127 | + ret = s->sptr; | ||
128 | + break; | ||
129 | + } | ||
130 | +#endif | ||
131 | + } | ||
132 | + | ||
133 | + fprintf(stderr, "sh_serial: unsupported write to 0x%02x\n", offs); | ||
134 | + assert(0); | ||
135 | +} | ||
136 | + | ||
137 | +static uint32_t sh_serial_ioport_read(void *opaque, uint32_t offs) | ||
138 | +{ | ||
139 | + sh_serial_state *s = opaque; | ||
140 | + uint32_t ret = ~0; | ||
141 | + | ||
142 | +#if 0 | ||
143 | + switch(offs) { | ||
144 | + case 0x00: | ||
145 | + ret = s->smr; | ||
146 | + break; | ||
147 | + case 0x04: | ||
148 | + ret = s->brr; | ||
149 | + break; | ||
150 | + case 0x08: | ||
151 | + ret = s->scr; | ||
152 | + break; | ||
153 | + case 0x14: | ||
154 | + ret = 0; | ||
155 | + break; | ||
156 | + } | ||
157 | +#endif | ||
158 | + if (s->feat & SH_SERIAL_FEAT_SCIF) { | ||
159 | + switch(offs) { | ||
160 | + case 0x10: /* FSR */ | ||
161 | + ret = 0; | ||
162 | + if (s->flags & SH_SERIAL_FLAG_TEND) | ||
163 | + ret |= (1 << 6); | ||
164 | + if (s->flags & SH_SERIAL_FLAG_TDE) | ||
165 | + ret |= (1 << 5); | ||
166 | + if (s->flags & SH_SERIAL_FLAG_BRK) | ||
167 | + ret |= (1 << 4); | ||
168 | + if (s->flags & SH_SERIAL_FLAG_RDF) | ||
169 | + ret |= (1 << 1); | ||
170 | + if (s->flags & SH_SERIAL_FLAG_DR) | ||
171 | + ret |= (1 << 0); | ||
172 | + | ||
173 | + if (s->scr & (1 << 5)) | ||
174 | + s->flags |= SH_SERIAL_FLAG_TDE | SH_SERIAL_FLAG_TEND; | ||
175 | + | ||
176 | + break; | ||
177 | +#if 0 | ||
178 | + case 0x18: | ||
179 | + ret = s->fcr; | ||
180 | + break; | ||
181 | +#endif | ||
182 | + case 0x1c: | ||
183 | + ret = s->rx_cnt; | ||
184 | + break; | ||
185 | + case 0x20: | ||
186 | + ret = s->sptr; | ||
187 | + break; | ||
188 | + case 0x24: | ||
189 | + ret = 0; | ||
190 | + break; | ||
191 | + } | ||
192 | + } | ||
193 | + else { | ||
194 | +#if 0 | ||
195 | + switch(offs) { | ||
196 | + case 0x0c: | ||
197 | + ret = s->dr; | ||
198 | + break; | ||
199 | + case 0x10: | ||
200 | + ret = 0; | ||
201 | + break; | ||
202 | + case 0x1c: | ||
203 | + ret = s->sptr; | ||
204 | + break; | ||
205 | + } | ||
206 | +#endif | ||
207 | + } | ||
208 | +#ifdef DEBUG_SERIAL | ||
209 | + printf("sh_serial: read base=0x%08lx offs=0x%02x val=0x%x\n", | ||
210 | + (unsigned long) s->base, offs, ret); | ||
211 | +#endif | ||
212 | + | ||
213 | + if (ret & ~((1 << 16) - 1)) { | ||
214 | + fprintf(stderr, "sh_serial: unsupported read from 0x%02x\n", offs); | ||
215 | + assert(0); | ||
216 | + } | ||
217 | + | ||
218 | + return ret; | ||
219 | +} | ||
220 | + | ||
221 | +static int sh_serial_can_receive(sh_serial_state *s) | ||
222 | +{ | ||
223 | + return 0; | ||
224 | +} | ||
225 | + | ||
226 | +static void sh_serial_receive_byte(sh_serial_state *s, int ch) | ||
227 | +{ | ||
228 | +} | ||
229 | + | ||
230 | +static void sh_serial_receive_break(sh_serial_state *s) | ||
231 | +{ | ||
232 | +} | ||
233 | + | ||
234 | +static int sh_serial_can_receive1(void *opaque) | ||
235 | +{ | ||
236 | + sh_serial_state *s = opaque; | ||
237 | + return sh_serial_can_receive(s); | ||
238 | +} | ||
239 | + | ||
240 | +static void sh_serial_receive1(void *opaque, const uint8_t *buf, int size) | ||
241 | +{ | ||
242 | + sh_serial_state *s = opaque; | ||
243 | + sh_serial_receive_byte(s, buf[0]); | ||
244 | +} | ||
245 | + | ||
246 | +static void sh_serial_event(void *opaque, int event) | ||
247 | +{ | ||
248 | + sh_serial_state *s = opaque; | ||
249 | + if (event == CHR_EVENT_BREAK) | ||
250 | + sh_serial_receive_break(s); | ||
251 | +} | ||
252 | + | ||
253 | +uint32_t sh_serial_read (void *opaque, target_phys_addr_t addr) | ||
254 | +{ | ||
255 | + sh_serial_state *s = opaque; | ||
256 | + return sh_serial_ioport_read(s, addr - s->base); | ||
257 | +} | ||
258 | + | ||
259 | +void sh_serial_write (void *opaque, | ||
260 | + target_phys_addr_t addr, uint32_t value) | ||
261 | +{ | ||
262 | + sh_serial_state *s = opaque; | ||
263 | + sh_serial_ioport_write(s, addr - s->base, value); | ||
264 | +} | ||
265 | + | ||
266 | +static CPUReadMemoryFunc *sh_serial_readfn[] = { | ||
267 | + &sh_serial_read, | ||
268 | + &sh_serial_read, | ||
269 | + &sh_serial_read, | ||
270 | +}; | ||
271 | + | ||
272 | +static CPUWriteMemoryFunc *sh_serial_writefn[] = { | ||
273 | + &sh_serial_write, | ||
274 | + &sh_serial_write, | ||
275 | + &sh_serial_write, | ||
276 | +}; | ||
277 | + | ||
278 | +void sh_serial_init (target_phys_addr_t base, int feat, | ||
279 | + uint32_t freq, CharDriverState *chr) | ||
280 | +{ | ||
281 | + sh_serial_state *s; | ||
282 | + int s_io_memory; | ||
283 | + | ||
284 | + s = qemu_mallocz(sizeof(sh_serial_state)); | ||
285 | + if (!s) | ||
286 | + return; | ||
287 | + | ||
288 | + s->base = base; | ||
289 | + s->feat = feat; | ||
290 | + s->flags = SH_SERIAL_FLAG_TEND | SH_SERIAL_FLAG_TDE; | ||
291 | + | ||
292 | + s->smr = 0; | ||
293 | + s->brr = 0xff; | ||
294 | + s->scr = 0; | ||
295 | + s->sptr = 0; | ||
296 | + | ||
297 | + if (feat & SH_SERIAL_FEAT_SCIF) { | ||
298 | + s->fcr = 0; | ||
299 | + } | ||
300 | + else { | ||
301 | + s->dr = 0xff; | ||
302 | + } | ||
303 | + | ||
304 | + s->rx_cnt = 0; | ||
305 | + | ||
306 | + s_io_memory = cpu_register_io_memory(0, sh_serial_readfn, | ||
307 | + sh_serial_writefn, s); | ||
308 | + cpu_register_physical_memory(base, 0x28, s_io_memory); | ||
309 | + | ||
310 | + s->chr = chr; | ||
311 | + | ||
312 | + if (chr) | ||
313 | + qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1, | ||
314 | + sh_serial_event, s); | ||
315 | +} |
vl.h
@@ -1523,6 +1523,11 @@ int sh7750_register_io_device(struct SH7750State *s, | @@ -1523,6 +1523,11 @@ int sh7750_register_io_device(struct SH7750State *s, | ||
1523 | #define TMU012_FEAT_EXTCLK (1 << 2) | 1523 | #define TMU012_FEAT_EXTCLK (1 << 2) |
1524 | void tmu012_init(uint32_t base, int feat, uint32_t freq); | 1524 | void tmu012_init(uint32_t base, int feat, uint32_t freq); |
1525 | 1525 | ||
1526 | +/* sh_serial.c */ | ||
1527 | +#define SH_SERIAL_FEAT_SCIF (1 << 0) | ||
1528 | +void sh_serial_init (target_phys_addr_t base, int feat, | ||
1529 | + uint32_t freq, CharDriverState *chr); | ||
1530 | + | ||
1526 | /* tc58128.c */ | 1531 | /* tc58128.c */ |
1527 | int tc58128_init(struct SH7750State *s, char *zone1, char *zone2); | 1532 | int tc58128_init(struct SH7750State *s, char *zone1, char *zone2); |
1528 | 1533 |