Revision 2f062c72
b/Makefile.target | ||
---|---|---|
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 |
b/hw/sh7750.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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, |
b/hw/sh7750_regnames.c | ||
---|---|---|
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) |
b/hw/sh7750_regs.h | ||
---|---|---|
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 */ |
b/hw/sh_serial.c | ||
---|---|---|
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 |
} |
b/vl.h | ||
---|---|---|
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 |
|
Also available in: Unified diff