Commit 77d4bc349abd61ba2e12327e40f95bfc4069f2a0

Authored by bellard
1 parent a2a444d6

PowerPC prep/chrp/pmac support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@863 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 3 changed files with 341 additions and 1 deletions
hw/pci.c
... ... @@ -470,6 +470,259 @@ void piix3_init(void)
470 470 piix3_reset(d);
471 471 }
472 472  
  473 +/* PREP pci init */
  474 +
  475 +static inline void set_config(PCIBridge *s, target_phys_addr_t addr)
  476 +{
  477 + int devfn, i;
  478 +
  479 + for(i = 0; i < 11; i++) {
  480 + if ((addr & (1 << (11 + i))) != 0)
  481 + break;
  482 + }
  483 + devfn = ((addr >> 8) & 7) | (i << 3);
  484 + s->config_reg = 0x80000000 | (addr & 0xfc) | (devfn << 8);
  485 +}
  486 +
  487 +static void PPC_PCIIO_writeb (target_phys_addr_t addr, uint32_t val)
  488 +{
  489 + PCIBridge *s = &pci_bridge;
  490 + set_config(s, addr);
  491 + pci_data_write(s, addr, val, 1);
  492 +}
  493 +
  494 +static void PPC_PCIIO_writew (target_phys_addr_t addr, uint32_t val)
  495 +{
  496 + PCIBridge *s = &pci_bridge;
  497 + set_config(s, addr);
  498 +#ifdef TARGET_WORDS_BIGENDIAN
  499 + val = bswap16(val);
  500 +#endif
  501 + pci_data_write(s, addr, val, 2);
  502 +}
  503 +
  504 +static void PPC_PCIIO_writel (target_phys_addr_t addr, uint32_t val)
  505 +{
  506 + PCIBridge *s = &pci_bridge;
  507 + set_config(s, addr);
  508 +#ifdef TARGET_WORDS_BIGENDIAN
  509 + val = bswap32(val);
  510 +#endif
  511 + pci_data_write(s, addr, val, 4);
  512 +}
  513 +
  514 +static uint32_t PPC_PCIIO_readb (target_phys_addr_t addr)
  515 +{
  516 + PCIBridge *s = &pci_bridge;
  517 + uint32_t val;
  518 + set_config(s, addr);
  519 + val = pci_data_read(s, addr, 1);
  520 + return val;
  521 +}
  522 +
  523 +static uint32_t PPC_PCIIO_readw (target_phys_addr_t addr)
  524 +{
  525 + PCIBridge *s = &pci_bridge;
  526 + uint32_t val;
  527 + set_config(s, addr);
  528 + val = pci_data_read(s, addr, 2);
  529 +#ifdef TARGET_WORDS_BIGENDIAN
  530 + val = bswap16(val);
  531 +#endif
  532 + return val;
  533 +}
  534 +
  535 +static uint32_t PPC_PCIIO_readl (target_phys_addr_t addr)
  536 +{
  537 + PCIBridge *s = &pci_bridge;
  538 + uint32_t val;
  539 + set_config(s, addr);
  540 + val = pci_data_read(s, addr, 4);
  541 +#ifdef TARGET_WORDS_BIGENDIAN
  542 + val = bswap32(val);
  543 +#endif
  544 + return val;
  545 +}
  546 +
  547 +static CPUWriteMemoryFunc *PPC_PCIIO_write[] = {
  548 + &PPC_PCIIO_writeb,
  549 + &PPC_PCIIO_writew,
  550 + &PPC_PCIIO_writel,
  551 +};
  552 +
  553 +static CPUReadMemoryFunc *PPC_PCIIO_read[] = {
  554 + &PPC_PCIIO_readb,
  555 + &PPC_PCIIO_readw,
  556 + &PPC_PCIIO_readl,
  557 +};
  558 +
  559 +void pci_prep_init(void)
  560 +{
  561 + PCIDevice *d;
  562 + int PPC_io_memory;
  563 +
  564 + PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read, PPC_PCIIO_write);
  565 + cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);
  566 +
  567 + d = pci_register_device("PREP PCI Bridge", sizeof(PCIDevice), 0, 0,
  568 + NULL, NULL);
  569 +
  570 + /* XXX: put correct IDs */
  571 + d->config[0x00] = 0x11; // vendor_id
  572 + d->config[0x01] = 0x10;
  573 + d->config[0x02] = 0x26; // device_id
  574 + d->config[0x03] = 0x00;
  575 + d->config[0x08] = 0x02; // revision
  576 + d->config[0x0a] = 0x04; // class_sub = pci2pci
  577 + d->config[0x0b] = 0x06; // class_base = PCI_bridge
  578 + d->config[0x0e] = 0x01; // header_type
  579 +}
  580 +
  581 +
  582 +/* pmac pci init */
  583 +
  584 +static void pci_pmac_config_writel (target_phys_addr_t addr, uint32_t val)
  585 +{
  586 + PCIBridge *s = &pci_bridge;
  587 +#ifdef TARGET_WORDS_BIGENDIAN
  588 + val = bswap32(val);
  589 +#endif
  590 + s->config_reg = val;
  591 +}
  592 +
  593 +static uint32_t pci_pmac_config_readl (target_phys_addr_t addr)
  594 +{
  595 + PCIBridge *s = &pci_bridge;
  596 + uint32_t val;
  597 +
  598 + val = s->config_reg;
  599 +#ifdef TARGET_WORDS_BIGENDIAN
  600 + val = bswap32(val);
  601 +#endif
  602 + return val;
  603 +}
  604 +
  605 +static CPUWriteMemoryFunc *pci_pmac_config_write[] = {
  606 + &pci_pmac_config_writel,
  607 + &pci_pmac_config_writel,
  608 + &pci_pmac_config_writel,
  609 +};
  610 +
  611 +static CPUReadMemoryFunc *pci_pmac_config_read[] = {
  612 + &pci_pmac_config_readl,
  613 + &pci_pmac_config_readl,
  614 + &pci_pmac_config_readl,
  615 +};
  616 +
  617 +static void pci_pmac_writeb (target_phys_addr_t addr, uint32_t val)
  618 +{
  619 + PCIBridge *s = &pci_bridge;
  620 + pci_data_write(s, addr, val, 1);
  621 +}
  622 +
  623 +static void pci_pmac_writew (target_phys_addr_t addr, uint32_t val)
  624 +{
  625 + PCIBridge *s = &pci_bridge;
  626 +#ifdef TARGET_WORDS_BIGENDIAN
  627 + val = bswap16(val);
  628 +#endif
  629 + pci_data_write(s, addr, val, 2);
  630 +}
  631 +
  632 +static void pci_pmac_writel (target_phys_addr_t addr, uint32_t val)
  633 +{
  634 + PCIBridge *s = &pci_bridge;
  635 +#ifdef TARGET_WORDS_BIGENDIAN
  636 + val = bswap32(val);
  637 +#endif
  638 + pci_data_write(s, addr, val, 4);
  639 +}
  640 +
  641 +static uint32_t pci_pmac_readb (target_phys_addr_t addr)
  642 +{
  643 + PCIBridge *s = &pci_bridge;
  644 + uint32_t val;
  645 + val = pci_data_read(s, addr, 1);
  646 + return val;
  647 +}
  648 +
  649 +static uint32_t pci_pmac_readw (target_phys_addr_t addr)
  650 +{
  651 + PCIBridge *s = &pci_bridge;
  652 + uint32_t val;
  653 + val = pci_data_read(s, addr, 2);
  654 +#ifdef TARGET_WORDS_BIGENDIAN
  655 + val = bswap16(val);
  656 +#endif
  657 + return val;
  658 +}
  659 +
  660 +static uint32_t pci_pmac_readl (target_phys_addr_t addr)
  661 +{
  662 + PCIBridge *s = &pci_bridge;
  663 + uint32_t val;
  664 +
  665 + val = pci_data_read(s, addr, 4);
  666 +#ifdef TARGET_WORDS_BIGENDIAN
  667 + val = bswap32(val);
  668 +#endif
  669 + return val;
  670 +}
  671 +
  672 +static CPUWriteMemoryFunc *pci_pmac_write[] = {
  673 + &pci_pmac_writeb,
  674 + &pci_pmac_writew,
  675 + &pci_pmac_writel,
  676 +};
  677 +
  678 +static CPUReadMemoryFunc *pci_pmac_read[] = {
  679 + &pci_pmac_readb,
  680 + &pci_pmac_readw,
  681 + &pci_pmac_readl,
  682 +};
  683 +
  684 +void pci_pmac_init(void)
  685 +{
  686 + PCIDevice *d;
  687 + int pci_mem_config, pci_mem_data;
  688 +
  689 + pci_mem_config = cpu_register_io_memory(0, pci_pmac_config_read,
  690 + pci_pmac_config_write);
  691 + pci_mem_data = cpu_register_io_memory(0, pci_pmac_read, pci_pmac_write);
  692 +
  693 + cpu_register_physical_memory(0xfec00000, 0x1000, pci_mem_config);
  694 + cpu_register_physical_memory(0xfee00000, 0x1000, pci_mem_data);
  695 +
  696 + d = pci_register_device("MPC106", sizeof(PCIDevice), 0, 0,
  697 + NULL, NULL);
  698 +
  699 + /* same values as PearPC - check this */
  700 + d->config[0x00] = 0x11; // vendor_id
  701 + d->config[0x01] = 0x10;
  702 + d->config[0x02] = 0x26; // device_id
  703 + d->config[0x03] = 0x00;
  704 + d->config[0x08] = 0x02; // revision
  705 + d->config[0x0a] = 0x04; // class_sub = pci2pci
  706 + d->config[0x0b] = 0x06; // class_base = PCI_bridge
  707 + d->config[0x0e] = 0x01; // header_type
  708 +
  709 + d->config[0x18] = 0x0; // primary_bus
  710 + d->config[0x19] = 0x1; // secondary_bus
  711 + d->config[0x1a] = 0x1; // subordinate_bus
  712 + d->config[0x1c] = 0x10; // io_base
  713 + d->config[0x1d] = 0x20; // io_limit
  714 +
  715 + d->config[0x20] = 0x80; // memory_base
  716 + d->config[0x21] = 0x80;
  717 + d->config[0x22] = 0x90; // memory_limit
  718 + d->config[0x23] = 0x80;
  719 +
  720 + d->config[0x24] = 0x00; // prefetchable_memory_base
  721 + d->config[0x25] = 0x84;
  722 + d->config[0x26] = 0x00; // prefetchable_memory_limit
  723 + d->config[0x27] = 0x85;
  724 +}
  725 +
473 726 /***********************************************************/
474 727 /* generic PCI irq support */
475 728  
... ... @@ -484,6 +737,11 @@ static inline int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
484 737 }
485 738  
486 739 /* 0 <= irq_num <= 3. level must be 0 or 1 */
  740 +#ifdef TARGET_PPC
  741 +void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
  742 +{
  743 +}
  744 +#else
487 745 void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
488 746 {
489 747 int irq_index, shift, pic_irq, pic_level;
... ... @@ -519,6 +777,7 @@ void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
519 777 pic_set_irq(pic_irq, pic_level);
520 778 }
521 779 }
  780 +#endif
522 781  
523 782 /***********************************************************/
524 783 /* monitor info on PCI */
... ... @@ -780,3 +1039,44 @@ void pci_bios_init(void)
780 1039 }
781 1040 }
782 1041 }
  1042 +
  1043 +/*
  1044 + * This function initializes the PCI devices as a normal PCI BIOS
  1045 + * would do. It is provided just in case the BIOS has no support for
  1046 + * PCI.
  1047 + */
  1048 +void pci_ppc_bios_init(void)
  1049 +{
  1050 + PCIBridge *s = &pci_bridge;
  1051 + PCIDevice **bus;
  1052 + int bus_num, devfn, i, irq;
  1053 + uint8_t elcr[2];
  1054 +
  1055 + pci_bios_io_addr = 0xc000;
  1056 + pci_bios_mem_addr = 0xc0000000;
  1057 +
  1058 +#if 0
  1059 + /* activate IRQ mappings */
  1060 + elcr[0] = 0x00;
  1061 + elcr[1] = 0x00;
  1062 + for(i = 0; i < 4; i++) {
  1063 + irq = pci_irqs[i];
  1064 + /* set to trigger level */
  1065 + elcr[irq >> 3] |= (1 << (irq & 7));
  1066 + /* activate irq remapping in PIIX */
  1067 + pci_config_writeb((PCIDevice *)piix3_state, 0x60 + i, irq);
  1068 + }
  1069 + isa_outb(elcr[0], 0x4d0);
  1070 + isa_outb(elcr[1], 0x4d1);
  1071 +#endif
  1072 +
  1073 + for(bus_num = 0; bus_num < 256; bus_num++) {
  1074 + bus = s->pci_bus[bus_num];
  1075 + if (bus) {
  1076 + for(devfn = 0; devfn < 256; devfn++) {
  1077 + if (bus[devfn])
  1078 + pci_bios_init_device(bus[devfn]);
  1079 + }
  1080 + }
  1081 + }
  1082 +}
... ...
... ... @@ -93,8 +93,11 @@ extern void __sigaction();
93 93 #define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
94 94 #endif
95 95  
  96 +#ifdef TARGET_PPC
  97 +#define DEFAULT_RAM_SIZE 144
  98 +#else
96 99 #define DEFAULT_RAM_SIZE 32
97   -
  100 +#endif
98 101 /* in ms */
99 102 #define GUI_REFRESH_INTERVAL 30
100 103  
... ... @@ -125,6 +128,7 @@ QEMUTimer *gui_timer;
125 128 int vm_running;
126 129 int audio_enabled = 0;
127 130 int pci_enabled = 0;
  131 +int prep_enabled = 0;
128 132  
129 133 /***********************************************************/
130 134 /* x86 ISA bus support */
... ... @@ -876,12 +880,17 @@ int serial_open_device(void)
876 880 /* use console for serial port */
877 881 return 0;
878 882 } else {
  883 +#if 0
  884 + /* Not satisfying */
879 885 if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
880 886 fprintf(stderr, "warning: could not create pseudo terminal for serial port\n");
881 887 return -1;
882 888 }
883 889 fprintf(stderr, "Serial port redirected to %s\n", slave_name);
884 890 return master_fd;
  891 +#else
  892 + return -1;
  893 +#endif
885 894 }
886 895 }
887 896  
... ... @@ -2005,6 +2014,7 @@ enum {
2005 2014 QEMU_OPTION_L,
2006 2015 QEMU_OPTION_no_code_copy,
2007 2016 QEMU_OPTION_pci,
  2017 + QEMU_OPTION_prep,
2008 2018 };
2009 2019  
2010 2020 typedef struct QEMUOption {
... ... @@ -2049,7 +2059,12 @@ const QEMUOption qemu_options[] = {
2049 2059 { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
2050 2060 { "L", HAS_ARG, QEMU_OPTION_L },
2051 2061 { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
  2062 +
  2063 + /* temporary options */
2052 2064 { "pci", 0, QEMU_OPTION_pci },
  2065 +#ifdef TARGET_PPC
  2066 + { "prep", 0, QEMU_OPTION_prep },
  2067 +#endif
2053 2068 { NULL },
2054 2069 };
2055 2070  
... ... @@ -2323,6 +2338,9 @@ int main(int argc, char **argv)
2323 2338 case QEMU_OPTION_pci:
2324 2339 pci_enabled = 1;
2325 2340 break;
  2341 + case QEMU_OPTION_prep:
  2342 + prep_enabled = 1;
  2343 + break;
2326 2344 }
2327 2345 }
2328 2346 }
... ...
... ... @@ -429,6 +429,11 @@ void piix3_init(void);
429 429 void pci_bios_init(void);
430 430 void pci_info(void);
431 431  
  432 +/* temporary: will be moved in platform specific file */
  433 +void pci_prep_init(void);
  434 +void pci_pmac_init(void);
  435 +void pci_ppc_bios_init(void);
  436 +
432 437 /* vga.c */
433 438  
434 439 #define VGA_RAM_SIZE (4096 * 1024)
... ... @@ -580,6 +585,23 @@ void ppc_init (int ram_size, int vga_ram_size, int boot_device,
580 585 DisplayState *ds, const char **fd_filename, int snapshot,
581 586 const char *kernel_filename, const char *kernel_cmdline,
582 587 const char *initrd_filename);
  588 +void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
  589 + DisplayState *ds, const char **fd_filename, int snapshot,
  590 + const char *kernel_filename, const char *kernel_cmdline,
  591 + const char *initrd_filename);
  592 +void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
  593 + DisplayState *ds, const char **fd_filename, int snapshot,
  594 + const char *kernel_filename, const char *kernel_cmdline,
  595 + const char *initrd_filename);
  596 +ppc_tb_t *cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq);
  597 +struct sysctrl_t;
  598 +int prep_NVRAM_init (struct sysctrl_t *sysctrl, uint32_t RAM_size,
  599 + uint32_t BIOS_size, int boot_device,
  600 + uint32_t kernel_image);
  601 +
  602 +extern CPUWriteMemoryFunc *PPC_io_write[];
  603 +extern CPUReadMemoryFunc *PPC_io_read[];
  604 +extern int prep_enabled;
583 605  
584 606 /* monitor.c */
585 607 void monitor_init(void);
... ...