Commit b4ed08e09e1afefff885baffbea6e092386addc2
1 parent
2aa2ab3a
Rename slavio_serial functions to escc, add clock rate and it_shift parameters
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6270 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
100 additions
and
79 deletions
hw/escc.c
| 1 | /* | 1 | /* |
| 2 | - * QEMU Sparc SLAVIO serial port emulation | 2 | + * QEMU ESCC (Z8030/Z8530/Z85C30/SCC/ESCC) serial port emulation |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2003-2005 Fabrice Bellard | 4 | * Copyright (c) 2003-2005 Fabrice Bellard |
| 5 | * | 5 | * |
| @@ -22,7 +22,7 @@ | @@ -22,7 +22,7 @@ | ||
| 22 | * THE SOFTWARE. | 22 | * THE SOFTWARE. |
| 23 | */ | 23 | */ |
| 24 | #include "hw.h" | 24 | #include "hw.h" |
| 25 | -#include "sun4m.h" | 25 | +#include "escc.h" |
| 26 | #include "qemu-char.h" | 26 | #include "qemu-char.h" |
| 27 | #include "console.h" | 27 | #include "console.h" |
| 28 | 28 | ||
| @@ -36,7 +36,7 @@ | @@ -36,7 +36,7 @@ | ||
| 36 | //#define DEBUG_MOUSE | 36 | //#define DEBUG_MOUSE |
| 37 | 37 | ||
| 38 | /* | 38 | /* |
| 39 | - * This is the serial port, mouse and keyboard part of chip STP2001 | 39 | + * On Sparc32 this is the serial port, mouse and keyboard part of chip STP2001 |
| 40 | * (Slave I/O), also produced as NCR89C105. See | 40 | * (Slave I/O), also produced as NCR89C105. See |
| 41 | * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt | 41 | * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt |
| 42 | * | 42 | * |
| @@ -44,6 +44,14 @@ | @@ -44,6 +44,14 @@ | ||
| 44 | * mouse and keyboard ports don't implement all functions and they are | 44 | * mouse and keyboard ports don't implement all functions and they are |
| 45 | * only asynchronous. There is no DMA. | 45 | * only asynchronous. There is no DMA. |
| 46 | * | 46 | * |
| 47 | + * Z85C30 is also used on PowerMacs. There are some small differences | ||
| 48 | + * between Sparc version (sunzilog) and PowerMac (pmac): | ||
| 49 | + * Offset between control and data registers | ||
| 50 | + * There is some kind of lockup bug, but we can ignore it | ||
| 51 | + * CTS is inverted | ||
| 52 | + * DMA on pmac using DBDMA chip | ||
| 53 | + * pmac can do IRDA and faster rates, sunzilog can only do 38400 | ||
| 54 | + * pmac baud rate generator clock is 3.6864 MHz, sunzilog 4.9152 MHz | ||
| 47 | */ | 55 | */ |
| 48 | 56 | ||
| 49 | /* | 57 | /* |
| @@ -102,13 +110,14 @@ typedef struct ChannelState { | @@ -102,13 +110,14 @@ typedef struct ChannelState { | ||
| 102 | CharDriverState *chr; | 110 | CharDriverState *chr; |
| 103 | int e0_mode, led_mode, caps_lock_mode, num_lock_mode; | 111 | int e0_mode, led_mode, caps_lock_mode, num_lock_mode; |
| 104 | int disabled; | 112 | int disabled; |
| 113 | + int clock; | ||
| 105 | } ChannelState; | 114 | } ChannelState; |
| 106 | 115 | ||
| 107 | struct SerialState { | 116 | struct SerialState { |
| 108 | struct ChannelState chn[2]; | 117 | struct ChannelState chn[2]; |
| 118 | + int it_shift; | ||
| 109 | }; | 119 | }; |
| 110 | 120 | ||
| 111 | -#define SERIAL_SIZE 8 | ||
| 112 | #define SERIAL_CTRL 0 | 121 | #define SERIAL_CTRL 0 |
| 113 | #define SERIAL_DATA 1 | 122 | #define SERIAL_DATA 1 |
| 114 | 123 | ||
| @@ -257,7 +266,7 @@ static uint32_t get_queue(void *opaque) | @@ -257,7 +266,7 @@ static uint32_t get_queue(void *opaque) | ||
| 257 | return val; | 266 | return val; |
| 258 | } | 267 | } |
| 259 | 268 | ||
| 260 | -static int slavio_serial_update_irq_chn(ChannelState *s) | 269 | +static int escc_update_irq_chn(ChannelState *s) |
| 261 | { | 270 | { |
| 262 | if ((((s->wregs[W_INTR] & INTR_TXINT) && s->txint == 1) || | 271 | if ((((s->wregs[W_INTR] & INTR_TXINT) && s->txint == 1) || |
| 263 | // tx ints enabled, pending | 272 | // tx ints enabled, pending |
| @@ -271,18 +280,18 @@ static int slavio_serial_update_irq_chn(ChannelState *s) | @@ -271,18 +280,18 @@ static int slavio_serial_update_irq_chn(ChannelState *s) | ||
| 271 | return 0; | 280 | return 0; |
| 272 | } | 281 | } |
| 273 | 282 | ||
| 274 | -static void slavio_serial_update_irq(ChannelState *s) | 283 | +static void escc_update_irq(ChannelState *s) |
| 275 | { | 284 | { |
| 276 | int irq; | 285 | int irq; |
| 277 | 286 | ||
| 278 | - irq = slavio_serial_update_irq_chn(s); | ||
| 279 | - irq |= slavio_serial_update_irq_chn(s->otherchn); | 287 | + irq = escc_update_irq_chn(s); |
| 288 | + irq |= escc_update_irq_chn(s->otherchn); | ||
| 280 | 289 | ||
| 281 | SER_DPRINTF("IRQ = %d\n", irq); | 290 | SER_DPRINTF("IRQ = %d\n", irq); |
| 282 | qemu_set_irq(s->irq, irq); | 291 | qemu_set_irq(s->irq, irq); |
| 283 | } | 292 | } |
| 284 | 293 | ||
| 285 | -static void slavio_serial_reset_chn(ChannelState *s) | 294 | +static void escc_reset_chn(ChannelState *s) |
| 286 | { | 295 | { |
| 287 | int i; | 296 | int i; |
| 288 | 297 | ||
| @@ -311,11 +320,11 @@ static void slavio_serial_reset_chn(ChannelState *s) | @@ -311,11 +320,11 @@ static void slavio_serial_reset_chn(ChannelState *s) | ||
| 311 | clear_queue(s); | 320 | clear_queue(s); |
| 312 | } | 321 | } |
| 313 | 322 | ||
| 314 | -static void slavio_serial_reset(void *opaque) | 323 | +static void escc_reset(void *opaque) |
| 315 | { | 324 | { |
| 316 | SerialState *s = opaque; | 325 | SerialState *s = opaque; |
| 317 | - slavio_serial_reset_chn(&s->chn[0]); | ||
| 318 | - slavio_serial_reset_chn(&s->chn[1]); | 326 | + escc_reset_chn(&s->chn[0]); |
| 327 | + escc_reset_chn(&s->chn[1]); | ||
| 319 | } | 328 | } |
| 320 | 329 | ||
| 321 | static inline void set_rxint(ChannelState *s) | 330 | static inline void set_rxint(ChannelState *s) |
| @@ -339,7 +348,7 @@ static inline void set_rxint(ChannelState *s) | @@ -339,7 +348,7 @@ static inline void set_rxint(ChannelState *s) | ||
| 339 | s->rregs[R_INTR] |= INTR_RXINTA; | 348 | s->rregs[R_INTR] |= INTR_RXINTA; |
| 340 | else | 349 | else |
| 341 | s->otherchn->rregs[R_INTR] |= INTR_RXINTB; | 350 | s->otherchn->rregs[R_INTR] |= INTR_RXINTB; |
| 342 | - slavio_serial_update_irq(s); | 351 | + escc_update_irq(s); |
| 343 | } | 352 | } |
| 344 | 353 | ||
| 345 | static inline void set_txint(ChannelState *s) | 354 | static inline void set_txint(ChannelState *s) |
| @@ -360,7 +369,7 @@ static inline void set_txint(ChannelState *s) | @@ -360,7 +369,7 @@ static inline void set_txint(ChannelState *s) | ||
| 360 | s->rregs[R_INTR] |= INTR_TXINTA; | 369 | s->rregs[R_INTR] |= INTR_TXINTA; |
| 361 | else | 370 | else |
| 362 | s->otherchn->rregs[R_INTR] |= INTR_TXINTB; | 371 | s->otherchn->rregs[R_INTR] |= INTR_TXINTB; |
| 363 | - slavio_serial_update_irq(s); | 372 | + escc_update_irq(s); |
| 364 | } | 373 | } |
| 365 | 374 | ||
| 366 | static inline void clr_rxint(ChannelState *s) | 375 | static inline void clr_rxint(ChannelState *s) |
| @@ -382,7 +391,7 @@ static inline void clr_rxint(ChannelState *s) | @@ -382,7 +391,7 @@ static inline void clr_rxint(ChannelState *s) | ||
| 382 | } | 391 | } |
| 383 | if (s->txint) | 392 | if (s->txint) |
| 384 | set_txint(s); | 393 | set_txint(s); |
| 385 | - slavio_serial_update_irq(s); | 394 | + escc_update_irq(s); |
| 386 | } | 395 | } |
| 387 | 396 | ||
| 388 | static inline void clr_txint(ChannelState *s) | 397 | static inline void clr_txint(ChannelState *s) |
| @@ -404,10 +413,10 @@ static inline void clr_txint(ChannelState *s) | @@ -404,10 +413,10 @@ static inline void clr_txint(ChannelState *s) | ||
| 404 | } | 413 | } |
| 405 | if (s->rxint) | 414 | if (s->rxint) |
| 406 | set_rxint(s); | 415 | set_rxint(s); |
| 407 | - slavio_serial_update_irq(s); | 416 | + escc_update_irq(s); |
| 408 | } | 417 | } |
| 409 | 418 | ||
| 410 | -static void slavio_serial_update_parameters(ChannelState *s) | 419 | +static void escc_update_parameters(ChannelState *s) |
| 411 | { | 420 | { |
| 412 | int speed, parity, data_bits, stop_bits; | 421 | int speed, parity, data_bits, stop_bits; |
| 413 | QEMUSerialSetParams ssp; | 422 | QEMUSerialSetParams ssp; |
| @@ -442,7 +451,7 @@ static void slavio_serial_update_parameters(ChannelState *s) | @@ -442,7 +451,7 @@ static void slavio_serial_update_parameters(ChannelState *s) | ||
| 442 | data_bits = 8; | 451 | data_bits = 8; |
| 443 | break; | 452 | break; |
| 444 | } | 453 | } |
| 445 | - speed = 2457600 / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2); | 454 | + speed = s->clock / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2); |
| 446 | switch (s->wregs[W_TXCTRL1] & TXCTRL1_CLKMSK) { | 455 | switch (s->wregs[W_TXCTRL1] & TXCTRL1_CLKMSK) { |
| 447 | case TXCTRL1_CLK1X: | 456 | case TXCTRL1_CLK1X: |
| 448 | break; | 457 | break; |
| @@ -466,8 +475,7 @@ static void slavio_serial_update_parameters(ChannelState *s) | @@ -466,8 +475,7 @@ static void slavio_serial_update_parameters(ChannelState *s) | ||
| 466 | qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); | 475 | qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); |
| 467 | } | 476 | } |
| 468 | 477 | ||
| 469 | -static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, | ||
| 470 | - uint32_t val) | 478 | +static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) |
| 471 | { | 479 | { |
| 472 | SerialState *serial = opaque; | 480 | SerialState *serial = opaque; |
| 473 | ChannelState *s; | 481 | ChannelState *s; |
| @@ -475,8 +483,8 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, | @@ -475,8 +483,8 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, | ||
| 475 | int newreg, channel; | 483 | int newreg, channel; |
| 476 | 484 | ||
| 477 | val &= 0xff; | 485 | val &= 0xff; |
| 478 | - saddr = (addr & 3) >> 1; | ||
| 479 | - channel = addr >> 2; | 486 | + saddr = (addr >> serial->it_shift) & 1; |
| 487 | + channel = (addr >> (serial->it_shift + 1)) & 1; | ||
| 480 | s = &serial->chn[channel]; | 488 | s = &serial->chn[channel]; |
| 481 | switch (saddr) { | 489 | switch (saddr) { |
| 482 | case SERIAL_CTRL: | 490 | case SERIAL_CTRL: |
| @@ -513,13 +521,13 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, | @@ -513,13 +521,13 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, | ||
| 513 | case W_TXCTRL1: | 521 | case W_TXCTRL1: |
| 514 | case W_TXCTRL2: | 522 | case W_TXCTRL2: |
| 515 | s->wregs[s->reg] = val; | 523 | s->wregs[s->reg] = val; |
| 516 | - slavio_serial_update_parameters(s); | 524 | + escc_update_parameters(s); |
| 517 | break; | 525 | break; |
| 518 | case W_BRGLO: | 526 | case W_BRGLO: |
| 519 | case W_BRGHI: | 527 | case W_BRGHI: |
| 520 | s->wregs[s->reg] = val; | 528 | s->wregs[s->reg] = val; |
| 521 | s->rregs[s->reg] = val; | 529 | s->rregs[s->reg] = val; |
| 522 | - slavio_serial_update_parameters(s); | 530 | + escc_update_parameters(s); |
| 523 | break; | 531 | break; |
| 524 | case W_MINTR: | 532 | case W_MINTR: |
| 525 | switch (val & MINTR_RST_MASK) { | 533 | switch (val & MINTR_RST_MASK) { |
| @@ -527,13 +535,13 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, | @@ -527,13 +535,13 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, | ||
| 527 | default: | 535 | default: |
| 528 | break; | 536 | break; |
| 529 | case MINTR_RST_B: | 537 | case MINTR_RST_B: |
| 530 | - slavio_serial_reset_chn(&serial->chn[0]); | 538 | + escc_reset_chn(&serial->chn[0]); |
| 531 | return; | 539 | return; |
| 532 | case MINTR_RST_A: | 540 | case MINTR_RST_A: |
| 533 | - slavio_serial_reset_chn(&serial->chn[1]); | 541 | + escc_reset_chn(&serial->chn[1]); |
| 534 | return; | 542 | return; |
| 535 | case MINTR_RST_ALL: | 543 | case MINTR_RST_ALL: |
| 536 | - slavio_serial_reset(serial); | 544 | + escc_reset(serial); |
| 537 | return; | 545 | return; |
| 538 | } | 546 | } |
| 539 | break; | 547 | break; |
| @@ -564,7 +572,7 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, | @@ -564,7 +572,7 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, | ||
| 564 | } | 572 | } |
| 565 | } | 573 | } |
| 566 | 574 | ||
| 567 | -static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr) | 575 | +static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr) |
| 568 | { | 576 | { |
| 569 | SerialState *serial = opaque; | 577 | SerialState *serial = opaque; |
| 570 | ChannelState *s; | 578 | ChannelState *s; |
| @@ -572,8 +580,8 @@ static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr) | @@ -572,8 +580,8 @@ static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr) | ||
| 572 | uint32_t ret; | 580 | uint32_t ret; |
| 573 | int channel; | 581 | int channel; |
| 574 | 582 | ||
| 575 | - saddr = (addr & 3) >> 1; | ||
| 576 | - channel = addr >> 2; | 583 | + saddr = (addr >> serial->it_shift) & 1; |
| 584 | + channel = (addr >> (serial->it_shift + 1)) & 1; | ||
| 577 | s = &serial->chn[channel]; | 585 | s = &serial->chn[channel]; |
| 578 | switch (saddr) { | 586 | switch (saddr) { |
| 579 | case SERIAL_CTRL: | 587 | case SERIAL_CTRL: |
| @@ -624,7 +632,7 @@ static void serial_receive_byte(ChannelState *s, int ch) | @@ -624,7 +632,7 @@ static void serial_receive_byte(ChannelState *s, int ch) | ||
| 624 | static void serial_receive_break(ChannelState *s) | 632 | static void serial_receive_break(ChannelState *s) |
| 625 | { | 633 | { |
| 626 | s->rregs[R_STATUS] |= STATUS_BRK; | 634 | s->rregs[R_STATUS] |= STATUS_BRK; |
| 627 | - slavio_serial_update_irq(s); | 635 | + escc_update_irq(s); |
| 628 | } | 636 | } |
| 629 | 637 | ||
| 630 | static void serial_receive1(void *opaque, const uint8_t *buf, int size) | 638 | static void serial_receive1(void *opaque, const uint8_t *buf, int size) |
| @@ -640,19 +648,19 @@ static void serial_event(void *opaque, int event) | @@ -640,19 +648,19 @@ static void serial_event(void *opaque, int event) | ||
| 640 | serial_receive_break(s); | 648 | serial_receive_break(s); |
| 641 | } | 649 | } |
| 642 | 650 | ||
| 643 | -static CPUReadMemoryFunc *slavio_serial_mem_read[3] = { | ||
| 644 | - slavio_serial_mem_readb, | 651 | +static CPUReadMemoryFunc *escc_mem_read[3] = { |
| 652 | + escc_mem_readb, | ||
| 645 | NULL, | 653 | NULL, |
| 646 | NULL, | 654 | NULL, |
| 647 | }; | 655 | }; |
| 648 | 656 | ||
| 649 | -static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = { | ||
| 650 | - slavio_serial_mem_writeb, | 657 | +static CPUWriteMemoryFunc *escc_mem_write[3] = { |
| 658 | + escc_mem_writeb, | ||
| 651 | NULL, | 659 | NULL, |
| 652 | NULL, | 660 | NULL, |
| 653 | }; | 661 | }; |
| 654 | 662 | ||
| 655 | -static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s) | 663 | +static void escc_save_chn(QEMUFile *f, ChannelState *s) |
| 656 | { | 664 | { |
| 657 | uint32_t tmp = 0; | 665 | uint32_t tmp = 0; |
| 658 | 666 | ||
| @@ -668,15 +676,15 @@ static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s) | @@ -668,15 +676,15 @@ static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s) | ||
| 668 | qemu_put_buffer(f, s->rregs, SERIAL_REGS); | 676 | qemu_put_buffer(f, s->rregs, SERIAL_REGS); |
| 669 | } | 677 | } |
| 670 | 678 | ||
| 671 | -static void slavio_serial_save(QEMUFile *f, void *opaque) | 679 | +static void escc_save(QEMUFile *f, void *opaque) |
| 672 | { | 680 | { |
| 673 | SerialState *s = opaque; | 681 | SerialState *s = opaque; |
| 674 | 682 | ||
| 675 | - slavio_serial_save_chn(f, &s->chn[0]); | ||
| 676 | - slavio_serial_save_chn(f, &s->chn[1]); | 683 | + escc_save_chn(f, &s->chn[0]); |
| 684 | + escc_save_chn(f, &s->chn[1]); | ||
| 677 | } | 685 | } |
| 678 | 686 | ||
| 679 | -static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id) | 687 | +static int escc_load_chn(QEMUFile *f, ChannelState *s, int version_id) |
| 680 | { | 688 | { |
| 681 | uint32_t tmp; | 689 | uint32_t tmp; |
| 682 | 690 | ||
| @@ -698,34 +706,37 @@ static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id) | @@ -698,34 +706,37 @@ static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id) | ||
| 698 | return 0; | 706 | return 0; |
| 699 | } | 707 | } |
| 700 | 708 | ||
| 701 | -static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id) | 709 | +static int escc_load(QEMUFile *f, void *opaque, int version_id) |
| 702 | { | 710 | { |
| 703 | SerialState *s = opaque; | 711 | SerialState *s = opaque; |
| 704 | int ret; | 712 | int ret; |
| 705 | 713 | ||
| 706 | - ret = slavio_serial_load_chn(f, &s->chn[0], version_id); | 714 | + ret = escc_load_chn(f, &s->chn[0], version_id); |
| 707 | if (ret != 0) | 715 | if (ret != 0) |
| 708 | return ret; | 716 | return ret; |
| 709 | - ret = slavio_serial_load_chn(f, &s->chn[1], version_id); | 717 | + ret = escc_load_chn(f, &s->chn[1], version_id); |
| 710 | return ret; | 718 | return ret; |
| 711 | 719 | ||
| 712 | } | 720 | } |
| 713 | 721 | ||
| 714 | -SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq, | ||
| 715 | - CharDriverState *chr1, CharDriverState *chr2) | 722 | +int escc_init(target_phys_addr_t base, qemu_irq irq, CharDriverState *chr1, |
| 723 | + CharDriverState *chr2, int clock, int it_shift) | ||
| 716 | { | 724 | { |
| 717 | - int slavio_serial_io_memory, i; | 725 | + int escc_io_memory, i; |
| 718 | SerialState *s; | 726 | SerialState *s; |
| 719 | 727 | ||
| 720 | s = qemu_mallocz(sizeof(SerialState)); | 728 | s = qemu_mallocz(sizeof(SerialState)); |
| 721 | if (!s) | 729 | if (!s) |
| 722 | - return NULL; | 730 | + return 0; |
| 723 | 731 | ||
| 724 | - slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, | ||
| 725 | - slavio_serial_mem_write, | ||
| 726 | - s); | ||
| 727 | - cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory); | 732 | + escc_io_memory = cpu_register_io_memory(0, escc_mem_read, |
| 733 | + escc_mem_write, | ||
| 734 | + s); | ||
| 735 | + if (base) | ||
| 736 | + cpu_register_physical_memory(base, ESCC_SIZE << it_shift, | ||
| 737 | + escc_io_memory); | ||
| 728 | 738 | ||
| 739 | + s->it_shift = it_shift; | ||
| 729 | s->chn[0].chr = chr1; | 740 | s->chn[0].chr = chr1; |
| 730 | s->chn[1].chr = chr2; | 741 | s->chn[1].chr = chr2; |
| 731 | s->chn[0].disabled = 0; | 742 | s->chn[0].disabled = 0; |
| @@ -735,6 +746,7 @@ SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq, | @@ -735,6 +746,7 @@ SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq, | ||
| 735 | s->chn[i].irq = irq; | 746 | s->chn[i].irq = irq; |
| 736 | s->chn[i].chn = 1 - i; | 747 | s->chn[i].chn = 1 - i; |
| 737 | s->chn[i].type = ser; | 748 | s->chn[i].type = ser; |
| 749 | + s->chn[i].clock = clock / 2; | ||
| 738 | if (s->chn[i].chr) { | 750 | if (s->chn[i].chr) { |
| 739 | qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive, | 751 | qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive, |
| 740 | serial_receive1, serial_event, &s->chn[i]); | 752 | serial_receive1, serial_event, &s->chn[i]); |
| @@ -742,11 +754,13 @@ SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq, | @@ -742,11 +754,13 @@ SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq, | ||
| 742 | } | 754 | } |
| 743 | s->chn[0].otherchn = &s->chn[1]; | 755 | s->chn[0].otherchn = &s->chn[1]; |
| 744 | s->chn[1].otherchn = &s->chn[0]; | 756 | s->chn[1].otherchn = &s->chn[0]; |
| 745 | - register_savevm("slavio_serial", base, 2, slavio_serial_save, | ||
| 746 | - slavio_serial_load, s); | ||
| 747 | - qemu_register_reset(slavio_serial_reset, s); | ||
| 748 | - slavio_serial_reset(s); | ||
| 749 | - return s; | 757 | + if (base) |
| 758 | + register_savevm("escc", base, 2, escc_save, escc_load, s); | ||
| 759 | + else | ||
| 760 | + register_savevm("escc", -1, 2, escc_save, escc_load, s); | ||
| 761 | + qemu_register_reset(escc_reset, s); | ||
| 762 | + escc_reset(s); | ||
| 763 | + return escc_io_memory; | ||
| 750 | } | 764 | } |
| 751 | 765 | ||
| 752 | static const uint8_t keycodes[128] = { | 766 | static const uint8_t keycodes[128] = { |
| @@ -887,7 +901,7 @@ static void sunmouse_event(void *opaque, | @@ -887,7 +901,7 @@ static void sunmouse_event(void *opaque, | ||
| 887 | } | 901 | } |
| 888 | 902 | ||
| 889 | void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq, | 903 | void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq, |
| 890 | - int disabled) | 904 | + int disabled, int clock, int it_shift) |
| 891 | { | 905 | { |
| 892 | int slavio_serial_io_memory, i; | 906 | int slavio_serial_io_memory, i; |
| 893 | SerialState *s; | 907 | SerialState *s; |
| @@ -895,10 +909,13 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq, | @@ -895,10 +909,13 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq, | ||
| 895 | s = qemu_mallocz(sizeof(SerialState)); | 909 | s = qemu_mallocz(sizeof(SerialState)); |
| 896 | if (!s) | 910 | if (!s) |
| 897 | return; | 911 | return; |
| 912 | + | ||
| 913 | + s->it_shift = it_shift; | ||
| 898 | for (i = 0; i < 2; i++) { | 914 | for (i = 0; i < 2; i++) { |
| 899 | s->chn[i].irq = irq; | 915 | s->chn[i].irq = irq; |
| 900 | s->chn[i].chn = 1 - i; | 916 | s->chn[i].chn = 1 - i; |
| 901 | s->chn[i].chr = NULL; | 917 | s->chn[i].chr = NULL; |
| 918 | + s->chn[i].clock = clock / 2; | ||
| 902 | } | 919 | } |
| 903 | s->chn[0].otherchn = &s->chn[1]; | 920 | s->chn[0].otherchn = &s->chn[1]; |
| 904 | s->chn[1].otherchn = &s->chn[0]; | 921 | s->chn[1].otherchn = &s->chn[0]; |
| @@ -907,16 +924,16 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq, | @@ -907,16 +924,16 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq, | ||
| 907 | s->chn[0].disabled = disabled; | 924 | s->chn[0].disabled = disabled; |
| 908 | s->chn[1].disabled = disabled; | 925 | s->chn[1].disabled = disabled; |
| 909 | 926 | ||
| 910 | - slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, | ||
| 911 | - slavio_serial_mem_write, | 927 | + slavio_serial_io_memory = cpu_register_io_memory(0, escc_mem_read, |
| 928 | + escc_mem_write, | ||
| 912 | s); | 929 | s); |
| 913 | - cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory); | 930 | + cpu_register_physical_memory(base, ESCC_SIZE << it_shift, |
| 931 | + slavio_serial_io_memory); | ||
| 914 | 932 | ||
| 915 | qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, | 933 | qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, |
| 916 | "QEMU Sun Mouse"); | 934 | "QEMU Sun Mouse"); |
| 917 | qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]); | 935 | qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]); |
| 918 | - register_savevm("slavio_serial_mouse", base, 2, slavio_serial_save, | ||
| 919 | - slavio_serial_load, s); | ||
| 920 | - qemu_register_reset(slavio_serial_reset, s); | ||
| 921 | - slavio_serial_reset(s); | 936 | + register_savevm("slavio_serial_mouse", base, 2, escc_save, escc_load, s); |
| 937 | + qemu_register_reset(escc_reset, s); | ||
| 938 | + escc_reset(s); | ||
| 922 | } | 939 | } |
hw/escc.h
0 โ 100644
hw/sun4m.c
| @@ -35,6 +35,7 @@ | @@ -35,6 +35,7 @@ | ||
| 35 | #include "pc.h" | 35 | #include "pc.h" |
| 36 | #include "isa.h" | 36 | #include "isa.h" |
| 37 | #include "fw_cfg.h" | 37 | #include "fw_cfg.h" |
| 38 | +#include "escc.h" | ||
| 38 | 39 | ||
| 39 | //#define DEBUG_IRQ | 40 | //#define DEBUG_IRQ |
| 40 | 41 | ||
| @@ -88,6 +89,8 @@ | @@ -88,6 +89,8 @@ | ||
| 88 | #define MAX_CPUS 16 | 89 | #define MAX_CPUS 16 |
| 89 | #define MAX_PILS 16 | 90 | #define MAX_PILS 16 |
| 90 | 91 | ||
| 92 | +#define ESCC_CLOCK 4915200 | ||
| 93 | + | ||
| 91 | struct sun4m_hwdef { | 94 | struct sun4m_hwdef { |
| 92 | target_phys_addr_t iommu_base, slavio_base; | 95 | target_phys_addr_t iommu_base, slavio_base; |
| 93 | target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base; | 96 | target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base; |
| @@ -552,11 +555,11 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size, | @@ -552,11 +555,11 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size, | ||
| 552 | slavio_cpu_irq, smp_cpus); | 555 | slavio_cpu_irq, smp_cpus); |
| 553 | 556 | ||
| 554 | slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq], | 557 | slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq], |
| 555 | - nographic); | 558 | + nographic, ESCC_CLOCK, 1); |
| 556 | // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device | 559 | // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device |
| 557 | // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device | 560 | // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device |
| 558 | - slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq], | ||
| 559 | - serial_hds[1], serial_hds[0]); | 561 | + escc_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq], serial_hds[1], |
| 562 | + serial_hds[0], ESCC_CLOCK, 1); | ||
| 560 | 563 | ||
| 561 | cpu_halt = qemu_allocate_irqs(cpu_halt_signal, NULL, 1); | 564 | cpu_halt = qemu_allocate_irqs(cpu_halt_signal, NULL, 1); |
| 562 | slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->apc_base, | 565 | slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->apc_base, |
| @@ -1345,11 +1348,11 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size, | @@ -1345,11 +1348,11 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size, | ||
| 1345 | sbi_cpu_irq, smp_cpus); | 1348 | sbi_cpu_irq, smp_cpus); |
| 1346 | 1349 | ||
| 1347 | slavio_serial_ms_kbd_init(hwdef->ms_kb_base, sbi_irq[hwdef->ms_kb_irq], | 1350 | slavio_serial_ms_kbd_init(hwdef->ms_kb_base, sbi_irq[hwdef->ms_kb_irq], |
| 1348 | - nographic); | 1351 | + nographic, ESCC_CLOCK, 1); |
| 1349 | // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device | 1352 | // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device |
| 1350 | // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device | 1353 | // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device |
| 1351 | - slavio_serial_init(hwdef->serial_base, sbi_irq[hwdef->ser_irq], | ||
| 1352 | - serial_hds[1], serial_hds[0]); | 1354 | + escc_init(hwdef->serial_base, sbi_irq[hwdef->ser_irq], serial_hds[1], |
| 1355 | + serial_hds[0], ESCC_CLOCK, 1); | ||
| 1353 | 1356 | ||
| 1354 | if (drive_get_max_bus(IF_SCSI) > 0) { | 1357 | if (drive_get_max_bus(IF_SCSI) > 0) { |
| 1355 | fprintf(stderr, "qemu: too many SCSI bus\n"); | 1358 | fprintf(stderr, "qemu: too many SCSI bus\n"); |
| @@ -1558,11 +1561,11 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size, | @@ -1558,11 +1561,11 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size, | ||
| 1558 | hwdef->nvram_size, 2); | 1561 | hwdef->nvram_size, 2); |
| 1559 | 1562 | ||
| 1560 | slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq], | 1563 | slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq], |
| 1561 | - nographic); | 1564 | + nographic, ESCC_CLOCK, 1); |
| 1562 | // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device | 1565 | // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device |
| 1563 | // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device | 1566 | // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device |
| 1564 | - slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq], | ||
| 1565 | - serial_hds[1], serial_hds[0]); | 1567 | + escc_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq], serial_hds[1], |
| 1568 | + serial_hds[0], ESCC_CLOCK, 1); | ||
| 1566 | 1569 | ||
| 1567 | slavio_misc = slavio_misc_init(0, 0, hwdef->aux1_base, 0, | 1570 | slavio_misc = slavio_misc_init(0, 0, hwdef->aux1_base, 0, |
| 1568 | slavio_irq[hwdef->me_irq], NULL, &fdc_tc); | 1571 | slavio_irq[hwdef->me_irq], NULL, &fdc_tc); |
hw/sun4m.h
| @@ -48,12 +48,6 @@ void sun4c_irq_info(void *opaque); | @@ -48,12 +48,6 @@ void sun4c_irq_info(void *opaque); | ||
| 48 | void slavio_timer_init_all(target_phys_addr_t base, qemu_irq master_irq, | 48 | void slavio_timer_init_all(target_phys_addr_t base, qemu_irq master_irq, |
| 49 | qemu_irq *cpu_irqs, unsigned int num_cpus); | 49 | qemu_irq *cpu_irqs, unsigned int num_cpus); |
| 50 | 50 | ||
| 51 | -/* slavio_serial.c */ | ||
| 52 | -SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq, | ||
| 53 | - CharDriverState *chr1, CharDriverState *chr2); | ||
| 54 | -void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq, | ||
| 55 | - int disabled); | ||
| 56 | - | ||
| 57 | /* slavio_misc.c */ | 51 | /* slavio_misc.c */ |
| 58 | void *slavio_misc_init(target_phys_addr_t base, target_phys_addr_t power_base, | 52 | void *slavio_misc_init(target_phys_addr_t base, target_phys_addr_t power_base, |
| 59 | target_phys_addr_t aux1_base, | 53 | target_phys_addr_t aux1_base, |