Commit 35db099ddb95c9761f665782b2f2cbe73f44e336

Authored by bellard
1 parent 6bcb76c3

allow host serial port usage (Blue Swirl)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2153 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 88 additions and 22 deletions
hw/slavio_serial.c
@@ -74,6 +74,8 @@ typedef enum { @@ -74,6 +74,8 @@ typedef enum {
74 chn_a, chn_b, 74 chn_a, chn_b,
75 } chn_id_t; 75 } chn_id_t;
76 76
  77 +#define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
  78 +
77 typedef enum { 79 typedef enum {
78 ser, kbd, mouse, 80 ser, kbd, mouse,
79 } chn_type_t; 81 } chn_type_t;
@@ -113,7 +115,7 @@ static void put_queue(void *opaque, int b) @@ -113,7 +115,7 @@ static void put_queue(void *opaque, int b)
113 ChannelState *s = opaque; 115 ChannelState *s = opaque;
114 SERIOQueue *q = &s->queue; 116 SERIOQueue *q = &s->queue;
115 117
116 - SER_DPRINTF("put: 0x%02x\n", b); 118 + SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
117 if (q->count >= SERIO_QUEUE_SIZE) 119 if (q->count >= SERIO_QUEUE_SIZE)
118 return; 120 return;
119 q->data[q->wptr] = b; 121 q->data[q->wptr] = b;
@@ -137,7 +139,7 @@ static uint32_t get_queue(void *opaque) @@ -137,7 +139,7 @@ static uint32_t get_queue(void *opaque)
137 q->rptr = 0; 139 q->rptr = 0;
138 q->count--; 140 q->count--;
139 } 141 }
140 - KBD_DPRINTF("get 0x%02x\n", val); 142 + KBD_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
141 if (q->count > 0) 143 if (q->count > 0)
142 serial_receive_byte(s, 0); 144 serial_receive_byte(s, 0);
143 return val; 145 return val;
@@ -198,11 +200,10 @@ static inline void clr_rxint(ChannelState *s) @@ -198,11 +200,10 @@ static inline void clr_rxint(ChannelState *s)
198 { 200 {
199 s->rxint = 0; 201 s->rxint = 0;
200 s->rxint_under_svc = 0; 202 s->rxint_under_svc = 0;
201 - if (s->chn == 0) 203 + if (s->chn == chn_a)
202 s->rregs[3] &= ~0x20; 204 s->rregs[3] &= ~0x20;
203 - else { 205 + else
204 s->otherchn->rregs[3] &= ~4; 206 s->otherchn->rregs[3] &= ~4;
205 - }  
206 if (s->txint) 207 if (s->txint)
207 set_txint(s); 208 set_txint(s);
208 else 209 else
@@ -215,11 +216,10 @@ static inline void set_rxint(ChannelState *s) @@ -215,11 +216,10 @@ static inline void set_rxint(ChannelState *s)
215 s->rxint = 1; 216 s->rxint = 1;
216 if (!s->txint_under_svc) { 217 if (!s->txint_under_svc) {
217 s->rxint_under_svc = 1; 218 s->rxint_under_svc = 1;
218 - if (s->chn == 0) 219 + if (s->chn == chn_a)
219 s->rregs[3] |= 0x20; 220 s->rregs[3] |= 0x20;
220 - else { 221 + else
221 s->otherchn->rregs[3] |= 4; 222 s->otherchn->rregs[3] |= 4;
222 - }  
223 s->rregs[2] = 4; 223 s->rregs[2] = 4;
224 slavio_serial_update_irq(s); 224 slavio_serial_update_irq(s);
225 } 225 }
@@ -229,11 +229,10 @@ static inline void clr_txint(ChannelState *s) @@ -229,11 +229,10 @@ static inline void clr_txint(ChannelState *s)
229 { 229 {
230 s->txint = 0; 230 s->txint = 0;
231 s->txint_under_svc = 0; 231 s->txint_under_svc = 0;
232 - if (s->chn == 0) 232 + if (s->chn == chn_a)
233 s->rregs[3] &= ~0x10; 233 s->rregs[3] &= ~0x10;
234 - else { 234 + else
235 s->otherchn->rregs[3] &= ~2; 235 s->otherchn->rregs[3] &= ~2;
236 - }  
237 if (s->rxint) 236 if (s->rxint)
238 set_rxint(s); 237 set_rxint(s);
239 else 238 else
@@ -246,16 +245,74 @@ static inline void set_txint(ChannelState *s) @@ -246,16 +245,74 @@ static inline void set_txint(ChannelState *s)
246 s->txint = 1; 245 s->txint = 1;
247 if (!s->rxint_under_svc) { 246 if (!s->rxint_under_svc) {
248 s->txint_under_svc = 1; 247 s->txint_under_svc = 1;
249 - if (s->chn == 0) 248 + if (s->chn == chn_a)
250 s->rregs[3] |= 0x10; 249 s->rregs[3] |= 0x10;
251 - else { 250 + else
252 s->otherchn->rregs[3] |= 2; 251 s->otherchn->rregs[3] |= 2;
253 - }  
254 s->rregs[2] = 0; 252 s->rregs[2] = 0;
255 slavio_serial_update_irq(s); 253 slavio_serial_update_irq(s);
256 } 254 }
257 } 255 }
258 256
  257 +static void slavio_serial_update_parameters(ChannelState *s)
  258 +{
  259 + int speed, parity, data_bits, stop_bits;
  260 + QEMUSerialSetParams ssp;
  261 +
  262 + if (!s->chr || s->type != ser)
  263 + return;
  264 +
  265 + if (s->wregs[4] & 1) {
  266 + if (s->wregs[4] & 2)
  267 + parity = 'E';
  268 + else
  269 + parity = 'O';
  270 + } else {
  271 + parity = 'N';
  272 + }
  273 + if ((s->wregs[4] & 0x0c) == 0x0c)
  274 + stop_bits = 2;
  275 + else
  276 + stop_bits = 1;
  277 + switch (s->wregs[5] & 0x60) {
  278 + case 0x00:
  279 + data_bits = 5;
  280 + break;
  281 + case 0x20:
  282 + data_bits = 7;
  283 + break;
  284 + case 0x40:
  285 + data_bits = 6;
  286 + break;
  287 + default:
  288 + case 0x60:
  289 + data_bits = 8;
  290 + break;
  291 + }
  292 + speed = 2457600 / ((s->wregs[12] | (s->wregs[13] << 8)) + 2);
  293 + switch (s->wregs[4] & 0xc0) {
  294 + case 0x00:
  295 + break;
  296 + case 0x40:
  297 + speed /= 16;
  298 + break;
  299 + case 0x80:
  300 + speed /= 32;
  301 + break;
  302 + default:
  303 + case 0xc0:
  304 + speed /= 64;
  305 + break;
  306 + }
  307 + ssp.speed = speed;
  308 + ssp.parity = parity;
  309 + ssp.data_bits = data_bits;
  310 + ssp.stop_bits = stop_bits;
  311 + SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
  312 + speed, parity, data_bits, stop_bits);
  313 + qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
  314 +}
  315 +
259 static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) 316 static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
260 { 317 {
261 SerialState *ser = opaque; 318 SerialState *ser = opaque;
@@ -269,7 +326,7 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint @@ -269,7 +326,7 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint
269 s = &ser->chn[channel]; 326 s = &ser->chn[channel];
270 switch (saddr) { 327 switch (saddr) {
271 case 0: 328 case 0:
272 - SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", channel? 'b' : 'a', s->reg, val & 0xff); 329 + SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, val & 0xff);
273 newreg = 0; 330 newreg = 0;
274 switch (s->reg) { 331 switch (s->reg) {
275 case 0: 332 case 0:
@@ -292,9 +349,18 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint @@ -292,9 +349,18 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint
292 break; 349 break;
293 } 350 }
294 break; 351 break;
295 - case 1 ... 8:  
296 - case 10 ... 15: 352 + case 1 ... 3:
  353 + case 6 ... 8:
  354 + case 10 ... 11:
  355 + case 14 ... 15:
  356 + s->wregs[s->reg] = val;
  357 + break;
  358 + case 4:
  359 + case 5:
  360 + case 12:
  361 + case 13:
297 s->wregs[s->reg] = val; 362 s->wregs[s->reg] = val;
  363 + slavio_serial_update_parameters(s);
298 break; 364 break;
299 case 9: 365 case 9:
300 switch (val & 0xc0) { 366 switch (val & 0xc0) {
@@ -321,7 +387,7 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint @@ -321,7 +387,7 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint
321 s->reg = 0; 387 s->reg = 0;
322 break; 388 break;
323 case 1: 389 case 1:
324 - SER_DPRINTF("Write channel %c, ch %d\n", channel? 'b' : 'a', val); 390 + SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
325 if (s->wregs[5] & 8) { // tx enabled 391 if (s->wregs[5] & 8) { // tx enabled
326 s->tx = val; 392 s->tx = val;
327 if (s->chr) 393 if (s->chr)
@@ -352,7 +418,7 @@ static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr) @@ -352,7 +418,7 @@ static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
352 s = &ser->chn[channel]; 418 s = &ser->chn[channel];
353 switch (saddr) { 419 switch (saddr) {
354 case 0: 420 case 0:
355 - SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", channel? 'b' : 'a', s->reg, s->rregs[s->reg]); 421 + SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, s->rregs[s->reg]);
356 ret = s->rregs[s->reg]; 422 ret = s->rregs[s->reg];
357 s->reg = 0; 423 s->reg = 0;
358 return ret; 424 return ret;
@@ -363,7 +429,7 @@ static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr) @@ -363,7 +429,7 @@ static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
363 ret = get_queue(s); 429 ret = get_queue(s);
364 else 430 else
365 ret = s->rx; 431 ret = s->rx;
366 - SER_DPRINTF("Read channel %c, ch %d\n", channel? 'b' : 'a', ret); 432 + SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
367 return ret; 433 return ret;
368 default: 434 default:
369 break; 435 break;
@@ -381,13 +447,13 @@ static int serial_can_receive(void *opaque) @@ -381,13 +447,13 @@ static int serial_can_receive(void *opaque)
381 ret = 0; 447 ret = 0;
382 else 448 else
383 ret = 1; 449 ret = 1;
384 - SER_DPRINTF("can receive %d\n", ret); 450 + //SER_DPRINTF("channel %c can receive %d\n", CHN_C(s), ret);
385 return ret; 451 return ret;
386 } 452 }
387 453
388 static void serial_receive_byte(ChannelState *s, int ch) 454 static void serial_receive_byte(ChannelState *s, int ch)
389 { 455 {
390 - SER_DPRINTF("put ch %d\n", ch); 456 + SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
391 s->rregs[0] |= 1; 457 s->rregs[0] |= 1;
392 s->rx = ch; 458 s->rx = ch;
393 set_rxint(s); 459 set_rxint(s);