Commit f2aa58c6f4a208350d05f0994e2e5422acc13c65
1 parent
611493d9
UniNorth PCI bridge support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@955 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
407 additions
and
48 deletions
hw/pci.c
... | ... | @@ -45,7 +45,7 @@ typedef struct PCIBridge { |
45 | 45 | PCIDevice **pci_bus[256]; |
46 | 46 | } PCIBridge; |
47 | 47 | |
48 | -static PCIBridge pci_bridge; | |
48 | +static PCIBridge pci_bridge[3]; | |
49 | 49 | target_phys_addr_t pci_mem_base; |
50 | 50 | static int pci_irq_index; |
51 | 51 | static uint32_t pci_irq_levels[4][PCI_IRQ_WORDS]; |
... | ... | @@ -56,7 +56,7 @@ PCIDevice *pci_register_device(const char *name, int instance_size, |
56 | 56 | PCIConfigReadFunc *config_read, |
57 | 57 | PCIConfigWriteFunc *config_write) |
58 | 58 | { |
59 | - PCIBridge *s = &pci_bridge; | |
59 | + PCIBridge *s = &pci_bridge[0]; | |
60 | 60 | PCIDevice *pci_dev, **bus; |
61 | 61 | |
62 | 62 | if (pci_irq_index >= PCI_DEVICES_MAX) |
... | ... | @@ -70,6 +70,10 @@ PCIDevice *pci_register_device(const char *name, int instance_size, |
70 | 70 | bus = s->pci_bus[bus_num]; |
71 | 71 | if (devfn < 0) { |
72 | 72 | for(devfn = 0 ; devfn < 256; devfn += 8) { |
73 | +#ifdef TARGET_PPC | |
74 | + if ((devfn >> 3) < 11) | |
75 | + continue; | |
76 | +#endif | |
73 | 77 | if (!bus[devfn]) |
74 | 78 | goto found; |
75 | 79 | } |
... | ... | @@ -425,7 +429,7 @@ static uint32_t pci_data_readl(void* opaque, uint32_t addr) |
425 | 429 | |
426 | 430 | void i440fx_init(void) |
427 | 431 | { |
428 | - PCIBridge *s = &pci_bridge; | |
432 | + PCIBridge *s = &pci_bridge[0]; | |
429 | 433 | PCIDevice *d; |
430 | 434 | |
431 | 435 | register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s); |
... | ... | @@ -604,7 +608,7 @@ static CPUReadMemoryFunc *PPC_PCIIO_read[] = { |
604 | 608 | |
605 | 609 | void pci_prep_init(void) |
606 | 610 | { |
607 | - PCIBridge *s = &pci_bridge; | |
611 | + PCIBridge *s = &pci_bridge[0]; | |
608 | 612 | PCIDevice *d; |
609 | 613 | int PPC_io_memory; |
610 | 614 | |
... | ... | @@ -629,7 +633,9 @@ void pci_prep_init(void) |
629 | 633 | |
630 | 634 | /* pmac pci init */ |
631 | 635 | |
632 | -static void pci_pmac_config_writel (void *opaque, target_phys_addr_t addr, uint32_t val) | |
636 | +/* Grackle PCI host */ | |
637 | +static void pci_grackle_config_writel (void *opaque, target_phys_addr_t addr, | |
638 | + uint32_t val) | |
633 | 639 | { |
634 | 640 | PCIBridge *s = opaque; |
635 | 641 | #ifdef TARGET_WORDS_BIGENDIAN |
... | ... | @@ -638,7 +644,7 @@ static void pci_pmac_config_writel (void *opaque, target_phys_addr_t addr, uint3 |
638 | 644 | s->config_reg = val; |
639 | 645 | } |
640 | 646 | |
641 | -static uint32_t pci_pmac_config_readl (void *opaque, target_phys_addr_t addr) | |
647 | +static uint32_t pci_grackle_config_readl (void *opaque, target_phys_addr_t addr) | |
642 | 648 | { |
643 | 649 | PCIBridge *s = opaque; |
644 | 650 | uint32_t val; |
... | ... | @@ -650,25 +656,27 @@ static uint32_t pci_pmac_config_readl (void *opaque, target_phys_addr_t addr) |
650 | 656 | return val; |
651 | 657 | } |
652 | 658 | |
653 | -static CPUWriteMemoryFunc *pci_pmac_config_write[] = { | |
654 | - &pci_pmac_config_writel, | |
655 | - &pci_pmac_config_writel, | |
656 | - &pci_pmac_config_writel, | |
659 | +static CPUWriteMemoryFunc *pci_grackle_config_write[] = { | |
660 | + &pci_grackle_config_writel, | |
661 | + &pci_grackle_config_writel, | |
662 | + &pci_grackle_config_writel, | |
657 | 663 | }; |
658 | 664 | |
659 | -static CPUReadMemoryFunc *pci_pmac_config_read[] = { | |
660 | - &pci_pmac_config_readl, | |
661 | - &pci_pmac_config_readl, | |
662 | - &pci_pmac_config_readl, | |
665 | +static CPUReadMemoryFunc *pci_grackle_config_read[] = { | |
666 | + &pci_grackle_config_readl, | |
667 | + &pci_grackle_config_readl, | |
668 | + &pci_grackle_config_readl, | |
663 | 669 | }; |
664 | 670 | |
665 | -static void pci_pmac_writeb (void *opaque, target_phys_addr_t addr, uint32_t val) | |
671 | +static void pci_grackle_writeb (void *opaque, target_phys_addr_t addr, | |
672 | + uint32_t val) | |
666 | 673 | { |
667 | 674 | PCIBridge *s = opaque; |
668 | 675 | pci_data_write(s, addr, val, 1); |
669 | 676 | } |
670 | 677 | |
671 | -static void pci_pmac_writew (void *opaque, target_phys_addr_t addr, uint32_t val) | |
678 | +static void pci_grackle_writew (void *opaque, target_phys_addr_t addr, | |
679 | + uint32_t val) | |
672 | 680 | { |
673 | 681 | PCIBridge *s = opaque; |
674 | 682 | #ifdef TARGET_WORDS_BIGENDIAN |
... | ... | @@ -677,7 +685,8 @@ static void pci_pmac_writew (void *opaque, target_phys_addr_t addr, uint32_t val |
677 | 685 | pci_data_write(s, addr, val, 2); |
678 | 686 | } |
679 | 687 | |
680 | -static void pci_pmac_writel (void *opaque, target_phys_addr_t addr, uint32_t val) | |
688 | +static void pci_grackle_writel (void *opaque, target_phys_addr_t addr, | |
689 | + uint32_t val) | |
681 | 690 | { |
682 | 691 | PCIBridge *s = opaque; |
683 | 692 | #ifdef TARGET_WORDS_BIGENDIAN |
... | ... | @@ -686,7 +695,7 @@ static void pci_pmac_writel (void *opaque, target_phys_addr_t addr, uint32_t val |
686 | 695 | pci_data_write(s, addr, val, 4); |
687 | 696 | } |
688 | 697 | |
689 | -static uint32_t pci_pmac_readb (void *opaque, target_phys_addr_t addr) | |
698 | +static uint32_t pci_grackle_readb (void *opaque, target_phys_addr_t addr) | |
690 | 699 | { |
691 | 700 | PCIBridge *s = opaque; |
692 | 701 | uint32_t val; |
... | ... | @@ -694,7 +703,7 @@ static uint32_t pci_pmac_readb (void *opaque, target_phys_addr_t addr) |
694 | 703 | return val; |
695 | 704 | } |
696 | 705 | |
697 | -static uint32_t pci_pmac_readw (void *opaque, target_phys_addr_t addr) | |
706 | +static uint32_t pci_grackle_readw (void *opaque, target_phys_addr_t addr) | |
698 | 707 | { |
699 | 708 | PCIBridge *s = opaque; |
700 | 709 | uint32_t val; |
... | ... | @@ -705,7 +714,131 @@ static uint32_t pci_pmac_readw (void *opaque, target_phys_addr_t addr) |
705 | 714 | return val; |
706 | 715 | } |
707 | 716 | |
708 | -static uint32_t pci_pmac_readl (void *opaque, target_phys_addr_t addr) | |
717 | +static uint32_t pci_grackle_readl (void *opaque, target_phys_addr_t addr) | |
718 | +{ | |
719 | + PCIBridge *s = opaque; | |
720 | + uint32_t val; | |
721 | + | |
722 | + val = pci_data_read(s, addr, 4); | |
723 | +#ifdef TARGET_WORDS_BIGENDIAN | |
724 | + val = bswap32(val); | |
725 | +#endif | |
726 | + return val; | |
727 | +} | |
728 | + | |
729 | +static CPUWriteMemoryFunc *pci_grackle_write[] = { | |
730 | + &pci_grackle_writeb, | |
731 | + &pci_grackle_writew, | |
732 | + &pci_grackle_writel, | |
733 | +}; | |
734 | + | |
735 | +static CPUReadMemoryFunc *pci_grackle_read[] = { | |
736 | + &pci_grackle_readb, | |
737 | + &pci_grackle_readw, | |
738 | + &pci_grackle_readl, | |
739 | +}; | |
740 | + | |
741 | +/* Uninorth PCI host (for all Mac99 and newer machines */ | |
742 | +static void pci_unin_main_config_writel (void *opaque, target_phys_addr_t addr, | |
743 | + uint32_t val) | |
744 | +{ | |
745 | + PCIBridge *s = opaque; | |
746 | + int i; | |
747 | + | |
748 | +#ifdef TARGET_WORDS_BIGENDIAN | |
749 | + val = bswap32(val); | |
750 | +#endif | |
751 | + | |
752 | + for (i = 11; i < 32; i++) { | |
753 | + if ((val & (1 << i)) != 0) | |
754 | + break; | |
755 | + } | |
756 | +#if 0 | |
757 | + s->config_reg = 0x80000000 | (1 << 16) | (val & 0x7FC) | (i << 11); | |
758 | +#else | |
759 | + s->config_reg = 0x80000000 | (0 << 16) | (val & 0x7FC) | (i << 11); | |
760 | +#endif | |
761 | +} | |
762 | + | |
763 | +static uint32_t pci_unin_main_config_readl (void *opaque, | |
764 | + target_phys_addr_t addr) | |
765 | +{ | |
766 | + PCIBridge *s = opaque; | |
767 | + uint32_t val; | |
768 | + int devfn; | |
769 | + | |
770 | + devfn = (s->config_reg >> 8) & 0xFF; | |
771 | + val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC); | |
772 | +#ifdef TARGET_WORDS_BIGENDIAN | |
773 | + val = bswap32(val); | |
774 | +#endif | |
775 | + | |
776 | + return val; | |
777 | +} | |
778 | + | |
779 | +static CPUWriteMemoryFunc *pci_unin_main_config_write[] = { | |
780 | + &pci_unin_main_config_writel, | |
781 | + &pci_unin_main_config_writel, | |
782 | + &pci_unin_main_config_writel, | |
783 | +}; | |
784 | + | |
785 | +static CPUReadMemoryFunc *pci_unin_main_config_read[] = { | |
786 | + &pci_unin_main_config_readl, | |
787 | + &pci_unin_main_config_readl, | |
788 | + &pci_unin_main_config_readl, | |
789 | +}; | |
790 | + | |
791 | +static void pci_unin_main_writeb (void *opaque, target_phys_addr_t addr, | |
792 | + uint32_t val) | |
793 | +{ | |
794 | + PCIBridge *s = opaque; | |
795 | + pci_data_write(s, addr & 7, val, 1); | |
796 | +} | |
797 | + | |
798 | +static void pci_unin_main_writew (void *opaque, target_phys_addr_t addr, | |
799 | + uint32_t val) | |
800 | +{ | |
801 | + PCIBridge *s = opaque; | |
802 | +#ifdef TARGET_WORDS_BIGENDIAN | |
803 | + val = bswap16(val); | |
804 | +#endif | |
805 | + pci_data_write(s, addr & 7, val, 2); | |
806 | +} | |
807 | + | |
808 | +static void pci_unin_main_writel (void *opaque, target_phys_addr_t addr, | |
809 | + uint32_t val) | |
810 | +{ | |
811 | + PCIBridge *s = opaque; | |
812 | +#ifdef TARGET_WORDS_BIGENDIAN | |
813 | + val = bswap32(val); | |
814 | +#endif | |
815 | + pci_data_write(s, addr & 7, val, 4); | |
816 | +} | |
817 | + | |
818 | +static uint32_t pci_unin_main_readb (void *opaque, target_phys_addr_t addr) | |
819 | +{ | |
820 | + PCIBridge *s = opaque; | |
821 | + uint32_t val; | |
822 | + | |
823 | + val = pci_data_read(s, addr & 7, 1); | |
824 | + | |
825 | + return val; | |
826 | +} | |
827 | + | |
828 | +static uint32_t pci_unin_main_readw (void *opaque, target_phys_addr_t addr) | |
829 | +{ | |
830 | + PCIBridge *s = opaque; | |
831 | + uint32_t val; | |
832 | + | |
833 | + val = pci_data_read(s, addr & 7, 2); | |
834 | +#ifdef TARGET_WORDS_BIGENDIAN | |
835 | + val = bswap16(val); | |
836 | +#endif | |
837 | + | |
838 | + return val; | |
839 | +} | |
840 | + | |
841 | +static uint32_t pci_unin_main_readl (void *opaque, target_phys_addr_t addr) | |
709 | 842 | { |
710 | 843 | PCIBridge *s = opaque; |
711 | 844 | uint32_t val; |
... | ... | @@ -714,37 +847,246 @@ static uint32_t pci_pmac_readl (void *opaque, target_phys_addr_t addr) |
714 | 847 | #ifdef TARGET_WORDS_BIGENDIAN |
715 | 848 | val = bswap32(val); |
716 | 849 | #endif |
850 | + | |
851 | + return val; | |
852 | +} | |
853 | + | |
854 | +static CPUWriteMemoryFunc *pci_unin_main_write[] = { | |
855 | + &pci_unin_main_writeb, | |
856 | + &pci_unin_main_writew, | |
857 | + &pci_unin_main_writel, | |
858 | +}; | |
859 | + | |
860 | +static CPUReadMemoryFunc *pci_unin_main_read[] = { | |
861 | + &pci_unin_main_readb, | |
862 | + &pci_unin_main_readw, | |
863 | + &pci_unin_main_readl, | |
864 | +}; | |
865 | + | |
866 | +static void pci_unin_config_writel (void *opaque, target_phys_addr_t addr, | |
867 | + uint32_t val) | |
868 | +{ | |
869 | + PCIBridge *s = opaque; | |
870 | + | |
871 | +#ifdef TARGET_WORDS_BIGENDIAN | |
872 | + val = bswap32(val); | |
873 | +#endif | |
874 | + s->config_reg = 0x80000000 | (val & ~0x00000001); | |
875 | +} | |
876 | + | |
877 | +static uint32_t pci_unin_config_readl (void *opaque, | |
878 | + target_phys_addr_t addr) | |
879 | +{ | |
880 | + PCIBridge *s = opaque; | |
881 | + uint32_t val; | |
882 | + | |
883 | + val = (s->config_reg | 0x00000001) & ~0x80000000; | |
884 | +#ifdef TARGET_WORDS_BIGENDIAN | |
885 | + val = bswap32(val); | |
886 | +#endif | |
887 | + | |
888 | + return val; | |
889 | +} | |
890 | + | |
891 | +static CPUWriteMemoryFunc *pci_unin_config_write[] = { | |
892 | + &pci_unin_config_writel, | |
893 | + &pci_unin_config_writel, | |
894 | + &pci_unin_config_writel, | |
895 | +}; | |
896 | + | |
897 | +static CPUReadMemoryFunc *pci_unin_config_read[] = { | |
898 | + &pci_unin_config_readl, | |
899 | + &pci_unin_config_readl, | |
900 | + &pci_unin_config_readl, | |
901 | +}; | |
902 | + | |
903 | +static void pci_unin_writeb (void *opaque, target_phys_addr_t addr, | |
904 | + uint32_t val) | |
905 | +{ | |
906 | + PCIBridge *s = opaque; | |
907 | + pci_data_write(s, addr & 3, val, 1); | |
908 | +} | |
909 | + | |
910 | +static void pci_unin_writew (void *opaque, target_phys_addr_t addr, | |
911 | + uint32_t val) | |
912 | +{ | |
913 | + PCIBridge *s = opaque; | |
914 | +#ifdef TARGET_WORDS_BIGENDIAN | |
915 | + val = bswap16(val); | |
916 | +#endif | |
917 | + pci_data_write(s, addr & 3, val, 2); | |
918 | +} | |
919 | + | |
920 | +static void pci_unin_writel (void *opaque, target_phys_addr_t addr, | |
921 | + uint32_t val) | |
922 | +{ | |
923 | + PCIBridge *s = opaque; | |
924 | +#ifdef TARGET_WORDS_BIGENDIAN | |
925 | + val = bswap32(val); | |
926 | +#endif | |
927 | + pci_data_write(s, addr & 3, val, 4); | |
928 | +} | |
929 | + | |
930 | +static uint32_t pci_unin_readb (void *opaque, target_phys_addr_t addr) | |
931 | +{ | |
932 | + PCIBridge *s = opaque; | |
933 | + uint32_t val; | |
934 | + | |
935 | + val = pci_data_read(s, addr & 3, 1); | |
936 | + | |
937 | + return val; | |
938 | +} | |
939 | + | |
940 | +static uint32_t pci_unin_readw (void *opaque, target_phys_addr_t addr) | |
941 | +{ | |
942 | + PCIBridge *s = opaque; | |
943 | + uint32_t val; | |
944 | + | |
945 | + val = pci_data_read(s, addr & 3, 2); | |
946 | +#ifdef TARGET_WORDS_BIGENDIAN | |
947 | + val = bswap16(val); | |
948 | +#endif | |
949 | + | |
950 | + return val; | |
951 | +} | |
952 | + | |
953 | +static uint32_t pci_unin_readl (void *opaque, target_phys_addr_t addr) | |
954 | +{ | |
955 | + PCIBridge *s = opaque; | |
956 | + uint32_t val; | |
957 | + | |
958 | + val = pci_data_read(s, addr & 3, 4); | |
959 | +#ifdef TARGET_WORDS_BIGENDIAN | |
960 | + val = bswap32(val); | |
961 | +#endif | |
962 | + | |
717 | 963 | return val; |
718 | 964 | } |
719 | 965 | |
720 | -static CPUWriteMemoryFunc *pci_pmac_write[] = { | |
721 | - &pci_pmac_writeb, | |
722 | - &pci_pmac_writew, | |
723 | - &pci_pmac_writel, | |
966 | +static CPUWriteMemoryFunc *pci_unin_write[] = { | |
967 | + &pci_unin_writeb, | |
968 | + &pci_unin_writew, | |
969 | + &pci_unin_writel, | |
724 | 970 | }; |
725 | 971 | |
726 | -static CPUReadMemoryFunc *pci_pmac_read[] = { | |
727 | - &pci_pmac_readb, | |
728 | - &pci_pmac_readw, | |
729 | - &pci_pmac_readl, | |
972 | +static CPUReadMemoryFunc *pci_unin_read[] = { | |
973 | + &pci_unin_readb, | |
974 | + &pci_unin_readw, | |
975 | + &pci_unin_readl, | |
730 | 976 | }; |
731 | 977 | |
732 | 978 | void pci_pmac_init(void) |
733 | 979 | { |
734 | - PCIBridge *s = &pci_bridge; | |
980 | + PCIBridge *s; | |
735 | 981 | PCIDevice *d; |
736 | 982 | int pci_mem_config, pci_mem_data; |
737 | 983 | |
738 | - pci_mem_config = cpu_register_io_memory(0, pci_pmac_config_read, | |
739 | - pci_pmac_config_write, s); | |
740 | - pci_mem_data = cpu_register_io_memory(0, pci_pmac_read, pci_pmac_write, s); | |
741 | - | |
742 | - cpu_register_physical_memory(0xfec00000, 0x1000, pci_mem_config); | |
743 | - cpu_register_physical_memory(0xfee00000, 0x1000, pci_mem_data); | |
744 | - | |
745 | - d = pci_register_device("MPC106", sizeof(PCIDevice), 0, 0, | |
984 | + /* Use values found on a real PowerMac */ | |
985 | + /* Uninorth main bus */ | |
986 | + s = &pci_bridge[0]; | |
987 | + pci_mem_config = cpu_register_io_memory(0, pci_unin_main_config_read, | |
988 | + pci_unin_main_config_write, s); | |
989 | + pci_mem_data = cpu_register_io_memory(0, pci_unin_main_read, | |
990 | + pci_unin_main_write, s); | |
991 | + cpu_register_physical_memory(0xf2800000, 0x1000, pci_mem_config); | |
992 | + cpu_register_physical_memory(0xf2c00000, 0x1000, pci_mem_data); | |
993 | + | |
994 | + d = pci_register_device("Uni-north main", sizeof(PCIDevice), 0, 11 << 3, | |
746 | 995 | NULL, NULL); |
996 | + d->config[0x00] = 0x6b; // vendor_id : Apple | |
997 | + d->config[0x01] = 0x10; | |
998 | + d->config[0x02] = 0x1F; // device_id | |
999 | + d->config[0x03] = 0x00; | |
1000 | + d->config[0x08] = 0x00; // revision | |
1001 | + d->config[0x0A] = 0x00; // class_sub = pci host | |
1002 | + d->config[0x0B] = 0x06; // class_base = PCI_bridge | |
1003 | + d->config[0x0C] = 0x08; // cache_line_size | |
1004 | + d->config[0x0D] = 0x10; // latency_timer | |
1005 | + d->config[0x0E] = 0x00; // header_type | |
1006 | + d->config[0x34] = 0x00; // capabilities_pointer | |
1007 | + | |
1008 | +#if 0 // XXX: not activated as PPC BIOS doesn't handle mutiple buses properly | |
1009 | + /* pci-to-pci bridge */ | |
1010 | + d = pci_register_device("Uni-north bridge", sizeof(PCIDevice), 0, 13 << 3, | |
1011 | + NULL, NULL); | |
1012 | + d->config[0x00] = 0x11; // vendor_id : TI | |
1013 | + d->config[0x01] = 0x10; | |
1014 | + d->config[0x02] = 0x26; // device_id | |
1015 | + d->config[0x03] = 0x00; | |
1016 | + d->config[0x08] = 0x05; // revision | |
1017 | + d->config[0x0A] = 0x04; // class_sub = pci2pci | |
1018 | + d->config[0x0B] = 0x06; // class_base = PCI_bridge | |
1019 | + d->config[0x0C] = 0x08; // cache_line_size | |
1020 | + d->config[0x0D] = 0x20; // latency_timer | |
1021 | + d->config[0x0E] = 0x01; // header_type | |
1022 | + | |
1023 | + d->config[0x18] = 0x01; // primary_bus | |
1024 | + d->config[0x19] = 0x02; // secondary_bus | |
1025 | + d->config[0x1A] = 0x02; // subordinate_bus | |
1026 | + d->config[0x1B] = 0x20; // secondary_latency_timer | |
1027 | + d->config[0x1C] = 0x11; // io_base | |
1028 | + d->config[0x1D] = 0x01; // io_limit | |
1029 | + d->config[0x20] = 0x00; // memory_base | |
1030 | + d->config[0x21] = 0x80; | |
1031 | + d->config[0x22] = 0x00; // memory_limit | |
1032 | + d->config[0x23] = 0x80; | |
1033 | + d->config[0x24] = 0x01; // prefetchable_memory_base | |
1034 | + d->config[0x25] = 0x80; | |
1035 | + d->config[0x26] = 0xF1; // prefectchable_memory_limit | |
1036 | + d->config[0x27] = 0x7F; | |
1037 | + // d->config[0x34] = 0xdc // capabilities_pointer | |
1038 | +#endif | |
1039 | +#if 0 // XXX: not needed for now | |
1040 | + /* Uninorth AGP bus */ | |
1041 | + s = &pci_bridge[1]; | |
1042 | + pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read, | |
1043 | + pci_unin_config_write, s); | |
1044 | + pci_mem_data = cpu_register_io_memory(0, pci_unin_read, | |
1045 | + pci_unin_write, s); | |
1046 | + cpu_register_physical_memory(0xf0800000, 0x1000, pci_mem_config); | |
1047 | + cpu_register_physical_memory(0xf0c00000, 0x1000, pci_mem_data); | |
1048 | + | |
1049 | + d = pci_register_device("Uni-north AGP", sizeof(PCIDevice), 0, 11 << 3, | |
1050 | + NULL, NULL); | |
1051 | + d->config[0x00] = 0x6b; // vendor_id : Apple | |
1052 | + d->config[0x01] = 0x10; | |
1053 | + d->config[0x02] = 0x20; // device_id | |
1054 | + d->config[0x03] = 0x00; | |
1055 | + d->config[0x08] = 0x00; // revision | |
1056 | + d->config[0x0A] = 0x00; // class_sub = pci host | |
1057 | + d->config[0x0B] = 0x06; // class_base = PCI_bridge | |
1058 | + d->config[0x0C] = 0x08; // cache_line_size | |
1059 | + d->config[0x0D] = 0x10; // latency_timer | |
1060 | + d->config[0x0E] = 0x00; // header_type | |
1061 | + // d->config[0x34] = 0x80; // capabilities_pointer | |
1062 | +#endif | |
747 | 1063 | |
1064 | +#if 0 // XXX: not needed for now | |
1065 | + /* Uninorth internal bus */ | |
1066 | + s = &pci_bridge[2]; | |
1067 | + pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read, | |
1068 | + pci_unin_config_write, s); | |
1069 | + pci_mem_data = cpu_register_io_memory(0, pci_unin_read, | |
1070 | + pci_unin_write, s); | |
1071 | + cpu_register_physical_memory(0xf4800000, 0x1000, pci_mem_config); | |
1072 | + cpu_register_physical_memory(0xf4c00000, 0x1000, pci_mem_data); | |
1073 | + | |
1074 | + d = pci_register_device("Uni-north internal", sizeof(PCIDevice), | |
1075 | + 3, 11 << 3, NULL, NULL); | |
1076 | + d->config[0x00] = 0x6b; // vendor_id : Apple | |
1077 | + d->config[0x01] = 0x10; | |
1078 | + d->config[0x02] = 0x1E; // device_id | |
1079 | + d->config[0x03] = 0x00; | |
1080 | + d->config[0x08] = 0x00; // revision | |
1081 | + d->config[0x0A] = 0x00; // class_sub = pci host | |
1082 | + d->config[0x0B] = 0x06; // class_base = PCI_bridge | |
1083 | + d->config[0x0C] = 0x08; // cache_line_size | |
1084 | + d->config[0x0D] = 0x10; // latency_timer | |
1085 | + d->config[0x0E] = 0x00; // header_type | |
1086 | + d->config[0x34] = 0x00; // capabilities_pointer | |
1087 | +#endif | |
1088 | + | |
1089 | +#if 0 // Grackle ? | |
748 | 1090 | /* same values as PearPC - check this */ |
749 | 1091 | d->config[0x00] = 0x11; // vendor_id |
750 | 1092 | d->config[0x01] = 0x10; |
... | ... | @@ -770,6 +1112,7 @@ void pci_pmac_init(void) |
770 | 1112 | d->config[0x25] = 0x84; |
771 | 1113 | d->config[0x26] = 0x00; // prefetchable_memory_limit |
772 | 1114 | d->config[0x27] = 0x85; |
1115 | +#endif | |
773 | 1116 | } |
774 | 1117 | |
775 | 1118 | /***********************************************************/ |
... | ... | @@ -878,7 +1221,7 @@ static void pci_info_device(PCIDevice *d) |
878 | 1221 | |
879 | 1222 | void pci_info(void) |
880 | 1223 | { |
881 | - PCIBridge *s = &pci_bridge; | |
1224 | + PCIBridge *s = &pci_bridge[0]; | |
882 | 1225 | PCIDevice **bus; |
883 | 1226 | int bus_num, devfn; |
884 | 1227 | |
... | ... | @@ -928,7 +1271,7 @@ static void isa_outl(uint32_t val, uint32_t addr) |
928 | 1271 | |
929 | 1272 | static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val) |
930 | 1273 | { |
931 | - PCIBridge *s = &pci_bridge; | |
1274 | + PCIBridge *s = &pci_bridge[0]; | |
932 | 1275 | s->config_reg = 0x80000000 | (d->bus_num << 16) | |
933 | 1276 | (d->devfn << 8) | addr; |
934 | 1277 | pci_data_write(s, 0, val, 4); |
... | ... | @@ -936,7 +1279,7 @@ static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val) |
936 | 1279 | |
937 | 1280 | static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val) |
938 | 1281 | { |
939 | - PCIBridge *s = &pci_bridge; | |
1282 | + PCIBridge *s = &pci_bridge[0]; | |
940 | 1283 | s->config_reg = 0x80000000 | (d->bus_num << 16) | |
941 | 1284 | (d->devfn << 8) | (addr & ~3); |
942 | 1285 | pci_data_write(s, addr & 3, val, 2); |
... | ... | @@ -944,7 +1287,7 @@ static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val) |
944 | 1287 | |
945 | 1288 | static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val) |
946 | 1289 | { |
947 | - PCIBridge *s = &pci_bridge; | |
1290 | + PCIBridge *s = &pci_bridge[0]; | |
948 | 1291 | s->config_reg = 0x80000000 | (d->bus_num << 16) | |
949 | 1292 | (d->devfn << 8) | (addr & ~3); |
950 | 1293 | pci_data_write(s, addr & 3, val, 1); |
... | ... | @@ -952,7 +1295,7 @@ static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val) |
952 | 1295 | |
953 | 1296 | static uint32_t pci_config_readl(PCIDevice *d, uint32_t addr) |
954 | 1297 | { |
955 | - PCIBridge *s = &pci_bridge; | |
1298 | + PCIBridge *s = &pci_bridge[0]; | |
956 | 1299 | s->config_reg = 0x80000000 | (d->bus_num << 16) | |
957 | 1300 | (d->devfn << 8) | addr; |
958 | 1301 | return pci_data_read(s, 0, 4); |
... | ... | @@ -960,7 +1303,7 @@ static uint32_t pci_config_readl(PCIDevice *d, uint32_t addr) |
960 | 1303 | |
961 | 1304 | static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr) |
962 | 1305 | { |
963 | - PCIBridge *s = &pci_bridge; | |
1306 | + PCIBridge *s = &pci_bridge[0]; | |
964 | 1307 | s->config_reg = 0x80000000 | (d->bus_num << 16) | |
965 | 1308 | (d->devfn << 8) | (addr & ~3); |
966 | 1309 | return pci_data_read(s, addr & 3, 2); |
... | ... | @@ -968,7 +1311,7 @@ static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr) |
968 | 1311 | |
969 | 1312 | static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr) |
970 | 1313 | { |
971 | - PCIBridge *s = &pci_bridge; | |
1314 | + PCIBridge *s = &pci_bridge[0]; | |
972 | 1315 | s->config_reg = 0x80000000 | (d->bus_num << 16) | |
973 | 1316 | (d->devfn << 8) | (addr & ~3); |
974 | 1317 | return pci_data_read(s, addr & 3, 1); |
... | ... | @@ -1036,8 +1379,21 @@ static void pci_bios_init_device(PCIDevice *d) |
1036 | 1379 | /* VGA: map frame buffer to default Bochs VBE address */ |
1037 | 1380 | pci_set_io_region_addr(d, 0, 0xE0000000); |
1038 | 1381 | break; |
1382 | + case 0x0800: | |
1383 | + /* PIC */ | |
1384 | + vendor_id = pci_config_readw(d, PCI_VENDOR_ID); | |
1385 | + device_id = pci_config_readw(d, PCI_DEVICE_ID); | |
1386 | + if (vendor_id == 0x1014) { | |
1387 | + /* IBM */ | |
1388 | + if (device_id == 0x0046 || device_id == 0xFFFF) { | |
1389 | + /* MPIC & MPIC2 */ | |
1390 | + pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000); | |
1391 | + } | |
1392 | + } | |
1393 | + break; | |
1039 | 1394 | case 0xff00: |
1040 | - if (vendor_id == 0x0106b && device_id == 0x0017) { | |
1395 | + if (vendor_id == 0x0106b && | |
1396 | + (device_id == 0x0017 || device_id == 0x0022)) { | |
1041 | 1397 | /* macio bridge */ |
1042 | 1398 | pci_set_io_region_addr(d, 0, 0x80800000); |
1043 | 1399 | } |
... | ... | @@ -1076,7 +1432,7 @@ static void pci_bios_init_device(PCIDevice *d) |
1076 | 1432 | */ |
1077 | 1433 | void pci_bios_init(void) |
1078 | 1434 | { |
1079 | - PCIBridge *s = &pci_bridge; | |
1435 | + PCIBridge *s = &pci_bridge[0]; | |
1080 | 1436 | PCIDevice **bus; |
1081 | 1437 | int bus_num, devfn, i, irq; |
1082 | 1438 | uint8_t elcr[2]; |
... | ... | @@ -1115,10 +1471,13 @@ void pci_bios_init(void) |
1115 | 1471 | */ |
1116 | 1472 | void pci_ppc_bios_init(void) |
1117 | 1473 | { |
1118 | - PCIBridge *s = &pci_bridge; | |
1474 | + PCIBridge *s = &pci_bridge[0]; | |
1119 | 1475 | PCIDevice **bus; |
1120 | - int bus_num, devfn, i, irq; | |
1476 | + int bus_num, devfn; | |
1477 | +#if 0 | |
1478 | + int i, irq; | |
1121 | 1479 | uint8_t elcr[2]; |
1480 | +#endif | |
1122 | 1481 | |
1123 | 1482 | pci_bios_io_addr = 0xc000; |
1124 | 1483 | pci_bios_mem_addr = 0xc0000000; | ... | ... |