tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE_BASE, SZ_16K, 0x20000000, 0xC, AC_R|AC_W|SA_G|SA_I)
 
-       tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x40000000, 0xC, AC_R|AC_W|SA_G|SA_I)
-       tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x80000000, 0xC, AC_R|AC_W|SA_G|SA_I)
-       tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0xC0000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE0_CFGBASE, SZ_16M, 0x40000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE1_CFGBASE, SZ_16M, 0x80000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE2_CFGBASE, SZ_16M, 0xC0000000, 0xC, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x50000000, 0xC, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x90000000, 0xC, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0xD0000000, 0xC, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 0xC, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I)
 
-       tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x00100000, 0xD, AC_R|AC_W|SA_G|SA_I)
-       tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x20100000, 0xD, AC_R|AC_W|SA_G|SA_I)
-       tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0x40100000, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE0_CFGBASE, SZ_16M, 0x00000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE1_CFGBASE, SZ_16M, 0x20000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE2_CFGBASE, SZ_16M, 0x40000000, 0xD, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x10000000, 0xD, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x30000000, 0xD, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0x50000000, 0xD, AC_R|AC_W|SA_G|SA_I)
 
 
 static struct pci_controller pcie_hose[3] = {{0},{0},{0}};
 
-void pcie_setup_hoses(void)
+void pcie_setup_hoses(int busno)
 {
        struct pci_controller *hose;
        int i, bus;
         * assume we're called after the PCIX hose is initialized, which takes
         * bus ID 0 and therefore start numbering PCIe's from 1.
         */
-       bus = 1;
+       bus = busno;
        for (i = 0; i <= 2; i++) {
                /* Check for katmai card presence */
                if (!katmai_pcie_card_present(i))
 
                hose = &pcie_hose[i];
                hose->first_busno = bus;
-               hose->last_busno  = bus;
-               bus++;
+               hose->last_busno = bus;
+               hose->current_busno = bus;
 
                /* setup mem resource */
                pci_set_region(hose->regions + 0,
                 * Config access can only go down stream
                 */
                hose->last_busno = pci_hose_scan(hose);
+               bus = hose->last_busno + 1;
 #endif
        }
 }
 
        tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE_BASE, SZ_16K, 0x20000000, 0xC, AC_R|AC_W|SA_G|SA_I)
 
-       tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x40000000, 0xC, AC_R|AC_W|SA_G|SA_I)
-       tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x80000000, 0xC, AC_R|AC_W|SA_G|SA_I)
-       tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0xC0000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE0_CFGBASE, SZ_16M, 0x40000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE1_CFGBASE, SZ_16M, 0x80000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE2_CFGBASE, SZ_16M, 0xC0000000, 0xC, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x50000000, 0xC, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x90000000, 0xC, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0xD0000000, 0xC, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 0xC, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I)
 
-       tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x00100000, 0xD, AC_R|AC_W|SA_G|SA_I)
-       tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x20100000, 0xD, AC_R|AC_W|SA_G|SA_I)
-       tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0x40100000, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE0_CFGBASE, SZ_16M, 0x00000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE1_CFGBASE, SZ_16M, 0x20000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+       tlbentry(CFG_PCIE2_CFGBASE, SZ_16M, 0x40000000, 0xD, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x10000000, 0xD, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x30000000, 0xD, AC_R|AC_W|SA_G|SA_I)
        tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0x50000000, 0xD, AC_R|AC_W|SA_G|SA_I)
 
 
 static struct pci_controller pcie_hose[3] = {{0},{0},{0}};
 
-void pcie_setup_hoses(void)
+void pcie_setup_hoses(int busno)
 {
        struct pci_controller *hose;
        int i, bus;
         * assume we're called after the PCIX hose is initialized, which takes
         * bus ID 0 and therefore start numbering PCIe's from 1.
         */
-       bus = 1;
+       bus = busno;
        for (i = 0; i <= 2; i++) {
                /* Check for yucca card presence */
                if (!yucca_pcie_card_present(i))
 
                hose = &pcie_hose[i];
                hose->first_busno = bus;
-               hose->last_busno  = bus;
-               bus++;
+               hose->last_busno = bus;
+               hose->current_busno = bus;
 
                /* setup mem resource */
                pci_set_region(hose->regions + 0,
                 * Config access can only go down stream
                 */
                hose->last_busno = pci_hose_scan(hose);
+               bus = hose->last_busno + 1;
 #endif
        }
 }
 
 static struct pci_controller ppc440_hose = {0};
 
 
-void pci_440_init (struct pci_controller *hose)
+int pci_440_init (struct pci_controller *hose)
 {
        int reg_num = 0;
 
        if ((strap & SDR0_SDSTP1_PISE_MASK) == 0) {
                printf("PCI: SDR0_STRP1[PISE] not set.\n");
                printf("PCI: Configuration aborted.\n");
-               return;
+               return -1;
        }
 #elif defined(CONFIG_440GP)
        unsigned long strap;
        if ((strap & CPC0_STRP1_PISE_MASK) == 0) {
                printf("PCI: CPC0_STRP1[PISE] not set.\n");
                printf("PCI: Configuration aborted.\n");
-               return;
+               return -1;
        }
 #endif
 #endif /* CONFIG_DISABLE_PISE_TEST */
         * PCI controller init
         *--------------------------------------------------------------------------*/
        hose->first_busno = 0;
-       hose->last_busno = 0xff;
+       hose->last_busno = 0;
 
        /* PCI I/O space */
        pci_set_region(hose->regions + reg_num++,
        if (pci_pre_init (hose) == 0) {
                printf("PCI: Board-specific initialization failed.\n");
                printf("PCI: Configuration aborted.\n");
-               return;
+               return -1;
        }
 
        pci_register_hose( hose );
 #endif
                hose->last_busno = pci_hose_scan(hose);
        }
+       return hose->last_busno;
 }
 
 void pci_init_board(void)
 {
-       pci_440_init (&ppc440_hose);
+       int busno;
+
+       busno = pci_440_init (&ppc440_hose);
 #if defined(CONFIG_440SPE)
-       pcie_setup_hoses();
+       pcie_setup_hoses(busno + 1);
 #endif
 }
 
 
        LNKW_X8                 = 0x8
 };
 
+static u8* pcie_get_base(struct pci_controller *hose, unsigned int devfn)
+{
+       u8 *base = (u8*)hose->cfg_data;
+
+       /* use local configuration space for the first bus */
+       if (PCI_BUS(devfn) == 0) {
+               if (hose->cfg_data == (u8*)CFG_PCIE0_CFGBASE)
+                       base = (u8*)CFG_PCIE0_XCFGBASE;
+               if (hose->cfg_data == (u8*)CFG_PCIE1_CFGBASE)
+                       base = (u8*)CFG_PCIE1_XCFGBASE;
+               if (hose->cfg_data == (u8*)CFG_PCIE2_CFGBASE)
+                       base = (u8*)CFG_PCIE2_XCFGBASE;
+       }
+
+       return base;
+}
+
 static void pcie_dmer_disable(void)
 {
        mtdcr (DCRN_PEGPL_CFG(DCRN_PCIE0_BASE),
                mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE)) & ~GPL_DMER_MASK_DISA);
 }
 
-
 static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
        int offset, int len, u32 *val) {
 
+       u8 *address;
        *val = 0;
+
+       /*
+        * Bus numbers are relative to hose->first_busno
+        */
+       devfn -= PCI_BDF(hose->first_busno, 0, 0);
+
        /*
-        * 440SPE implements only one function per port
+        * NOTICE: configuration space ranges are currenlty mapped only for
+        * the first 16 buses, so such limit must be imposed. In case more
+        * buses are required the TLB settings in board/amcc/<board>/init.S
+        * need to be altered accordingly (one bus takes 1 MB of memory space).
         */
-       if (!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 1)))
+       if (PCI_BUS(devfn) >= 16)
                return 0;
 
-       devfn = PCI_BDF(0,0,0);
+       /*
+        * Only single device/single function is supported for the primary and
+        * secondary buses of the 440SPe host bridge.
+        */
+       if ((!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 0))) &&
+               ((PCI_BUS(devfn) == 0) || (PCI_BUS(devfn) == 1)))
+               return 0;
+               
+       address = pcie_get_base(hose, devfn);
        offset += devfn << 4;
 
        /*
 static int pcie_write_config(struct pci_controller *hose, unsigned int devfn,
        int offset, int len, u32 val) {
 
+       u8 *address;
+       
        /*
-        * 440SPE implements only one function per port
+        * Bus numbers are relative to hose->first_busno
         */
-       if (!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 1)))
+       devfn -= PCI_BDF(hose->first_busno, 0, 0);
+       
+       /*
+        * Same constraints as in pcie_read_config().
+        */
+       if (PCI_BUS(devfn) >= 16)
                return 0;
 
-       devfn = PCI_BDF(0,0,0);
+       if ((!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 0))) &&
+               ((PCI_BUS(devfn) == 0) || (PCI_BUS(devfn) == 1)))
+               return 0;
+       
+       address = pcie_get_base(hose, devfn);
        offset += devfn << 4;
 
        /*
        u32 v;
        int rv;
 
-       rv =  pcie_read_config(hose, dev, offset, 1, &v);
+       rv = pcie_read_config(hose, dev, offset, 1, &v);
        *val = (u8)v;
        return rv;
 }
        volatile void *rmbase = NULL;
 
        pci_set_ops(hose,
-                   pcie_read_config_byte,
-                   pcie_read_config_word,
-                   pcie_read_config_dword,
-                   pcie_write_config_byte,
-                   pcie_write_config_word,
-                   pcie_write_config_dword);
+               pcie_read_config_byte,
+               pcie_read_config_word,
+               pcie_read_config_dword,
+               pcie_write_config_byte,
+               pcie_write_config_word,
+               pcie_write_config_dword);
 
        switch (port) {
        case 0:
        /*
         * Set bus numbers on our root port
         */
-       if (ppc440spe_revB()) {
-               out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0);
-               out_8((u8 *)mbase + PCI_SECONDARY_BUS, 1);
-               out_8((u8 *)mbase + PCI_SUBORDINATE_BUS, 1);
-       } else {
-               out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0);
-               out_8((u8 *)mbase + PCI_SECONDARY_BUS, 0);
-       }
+       out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0);
+       out_8((u8 *)mbase + PCI_SECONDARY_BUS, 1);
+       out_8((u8 *)mbase + PCI_SUBORDINATE_BUS, 1);
 
        /*
         * Set up outbound translation to hose->mem_space from PLB
                 in_le16((u16 *)(mbase + PCI_COMMAND)) |
                 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
        printf("PCIE:%d successfully set as rootpoint\n",port);
+       
+       /* Set Device and Vendor Id */
+       switch (port) {
+       case 0:
+               out_le16(mbase + 0x200, 0xaaa0);
+               out_le16(mbase + 0x202, 0xbed0);
+               break;
+       case 1:
+               out_le16(mbase + 0x200, 0xaaa1);
+               out_le16(mbase + 0x202, 0xbed1);
+               break;
+       case 2:
+               out_le16(mbase + 0x200, 0xaaa2);
+               out_le16(mbase + 0x202, 0xbed2);
+               break;
+       default:
+               out_le16(mbase + 0x200, 0xaaa3);
+               out_le16(mbase + 0x202, 0xbed3);
+       }
+
+       /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
+       out_le32(mbase + 0x208, 0x06040001);
+
 }
 
 int ppc440spe_setup_pcie_endpoint(struct pci_controller *hose, int port)
 
        /* Enable I/O, Mem, and Busmaster cycles */
        out_le16((u16 *)(mbase + PCI_COMMAND),
-                in_le16((u16 *)(mbase + PCI_COMMAND)) |
-                PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+               in_le16((u16 *)(mbase + PCI_COMMAND)) |
+               PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
        out_le16(mbase + 0x200,0xcaad);                 /* Setting vendor ID */
        out_le16(mbase + 0x202,0xfeed);                 /* Setting device ID */
        attempts = 10;
 
 #   endif
     int            is_pci_host         (struct pci_controller *);
 #if defined(CONFIG_440SPE)
-   void pcie_setup_hoses(void);
+   void pcie_setup_hoses(int busno);
 #endif
 #endif
 
 
 #define CFG_PCIE_BASE          0xe0000000      /* PCIe UTL regs */
 
 #define CFG_PCIE0_CFGBASE      0xc0000000
-#define CFG_PCIE0_XCFGBASE     0xc0000400
-#define CFG_PCIE1_CFGBASE      0xc0001000
-#define CFG_PCIE1_XCFGBASE     0xc0001400
-#define CFG_PCIE2_CFGBASE      0xc0002000
-#define CFG_PCIE2_XCFGBASE     0xc0002400
+#define CFG_PCIE1_CFGBASE      0xc1000000
+#define CFG_PCIE2_CFGBASE      0xc2000000
+#define CFG_PCIE0_XCFGBASE     0xc3000000
+#define CFG_PCIE1_XCFGBASE     0xc3001000
+#define CFG_PCIE2_XCFGBASE     0xc3002000
 
 /* System RAM mapped to PCI space */
 #define CONFIG_PCI_SYS_MEM_BUS CFG_SDRAM_BASE
 
 #define CFG_PCIE_BASE          0xe0000000      /* PCIe UTL regs */
 
 #define CFG_PCIE0_CFGBASE      0xc0000000
-#define CFG_PCIE0_XCFGBASE     0xc0000400
-#define CFG_PCIE1_CFGBASE      0xc0001000
-#define CFG_PCIE1_XCFGBASE     0xc0001400
-#define CFG_PCIE2_CFGBASE      0xc0002000
-#define CFG_PCIE2_XCFGBASE     0xc0002400
+#define CFG_PCIE1_CFGBASE      0xc1000000
+#define CFG_PCIE2_CFGBASE      0xc2000000
+#define CFG_PCIE0_XCFGBASE     0xc3000000
+#define CFG_PCIE1_XCFGBASE     0xc3001000
+#define CFG_PCIE2_XCFGBASE     0xc3002000
 
 /* System RAM mapped to PCI space */
 #define CONFIG_PCI_SYS_MEM_BUS CFG_SDRAM_BASE