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 | 476 | endif |
477 | 477 | ifeq ($(TARGET_BASE_ARCH), sh4) |
478 | 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 | 480 | endif |
481 | 481 | ifeq ($(TARGET_BASE_ARCH), m68k) |
482 | 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 | 27 | #include "sh7750_regs.h" |
28 | 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 | 30 | #define NB_DEVICES 4 |
38 | 31 | |
39 | 32 | typedef struct SH7750State { |
... | ... | @@ -43,27 +36,6 @@ typedef struct SH7750State { |
43 | 36 | uint32_t periph_freq; |
44 | 37 | /* SDRAM controller */ |
45 | 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 | 39 | /* IO ports */ |
68 | 40 | uint16_t gpioic; |
69 | 41 | uint32_t pctra; |
... | ... | @@ -84,263 +56,6 @@ typedef struct SH7750State { |
84 | 56 | |
85 | 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 | 61 | I/O ports |
... | ... | @@ -472,17 +187,7 @@ static void ignore_access(const char *kind, target_phys_addr_t addr) |
472 | 187 | |
473 | 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 | 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 | 191 | default: |
487 | 192 | error_access("byte read", addr); |
488 | 193 | assert(0); |
... | ... | @@ -492,20 +197,12 @@ static uint32_t sh7750_mem_readb(void *opaque, target_phys_addr_t addr) |
492 | 197 | static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr) |
493 | 198 | { |
494 | 199 | SH7750State *s = opaque; |
495 | - uint16_t r; | |
496 | 200 | |
497 | 201 | switch (addr) { |
498 | 202 | case SH7750_RFCR_A7: |
499 | 203 | fprintf(stderr, |
500 | 204 | "Read access to refresh count register, incrementing\n"); |
501 | 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 | 206 | case SH7750_PDTRA_A7: |
510 | 207 | return porta_lines(s); |
511 | 208 | case SH7750_PDTRB_A7: |
... | ... | @@ -554,34 +251,12 @@ static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr) |
554 | 251 | static void sh7750_mem_writeb(void *opaque, target_phys_addr_t addr, |
555 | 252 | uint32_t mem_value) |
556 | 253 | { |
557 | - SH7750State *s = opaque; | |
558 | - | |
559 | 254 | switch (addr) { |
560 | 255 | /* PRECHARGE ? XXXXX */ |
561 | 256 | case SH7750_PRECHARGE0_A7: |
562 | 257 | case SH7750_PRECHARGE1_A7: |
563 | 258 | ignore_access("byte write", addr); |
564 | 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 | 260 | default: |
586 | 261 | error_access("byte write", addr); |
587 | 262 | assert(0); |
... | ... | @@ -596,8 +271,6 @@ static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr, |
596 | 271 | |
597 | 272 | switch (addr) { |
598 | 273 | /* SDRAM controller */ |
599 | - case SH7750_SCBRR1_A7: | |
600 | - case SH7750_SCBRR2_A7: | |
601 | 274 | case SH7750_BCR2_A7: |
602 | 275 | case SH7750_BCR3_A7: |
603 | 276 | case SH7750_RTCOR_A7: |
... | ... | @@ -620,19 +293,6 @@ static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr, |
620 | 293 | fprintf(stderr, "Write access to refresh count register\n"); |
621 | 294 | s->rfcr = mem_value; |
622 | 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 | 296 | case SH7750_GPIOIC_A7: |
637 | 297 | s->gpioic = mem_value; |
638 | 298 | if (mem_value != 0) { |
... | ... | @@ -734,7 +394,10 @@ SH7750State *sh7750_init(CPUSH4State * cpu) |
734 | 394 | sh7750_mem_read, |
735 | 395 | sh7750_mem_write, s); |
736 | 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 | 402 | tmu012_init(0x1fd80000, |
740 | 403 | TMU012_FEAT_TOCR | TMU012_FEAT_3CHAN | TMU012_FEAT_EXTCLK, | ... | ... |
hw/sh7750_regnames.c
... | ... | @@ -70,24 +70,6 @@ static regname_t regnames[] = { |
70 | 70 | REGNAME(SH7750_CHCR2_A7) |
71 | 71 | REGNAME(SH7750_CHCR3_A7) |
72 | 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 | 73 | REGNAME(SH7750_PCTRA_A7) |
92 | 74 | REGNAME(SH7750_PDTRA_A7) |
93 | 75 | REGNAME(SH7750_PCTRB_A7) | ... | ... |
hw/sh7750_regs.h
... | ... | @@ -1169,231 +1169,6 @@ |
1169 | 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 | 1172 | * I/O Ports |
1398 | 1173 | */ |
1399 | 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 | 1523 | #define TMU012_FEAT_EXTCLK (1 << 2) |
1524 | 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 | 1531 | /* tc58128.c */ |
1527 | 1532 | int tc58128_init(struct SH7750State *s, char *zone1, char *zone2); |
1528 | 1533 | ... | ... |