Annotation of qemu/roms/openbios/drivers/pci.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *   OpenBIOS pci driver
                      3:  *
                      4:  *   This driver is compliant to the
                      5:  *   PCI bus binding to IEEE 1275-1994 Rev 2.1
                      6:  *
                      7:  *   (C) 2004 Stefan Reinauer <[email protected]>
                      8:  *   (C) 2005 Ed Schouten <[email protected]>
                      9:  *
                     10:  *   Some parts from OpenHackWare-0.4, Copyright (c) 2004-2005 Jocelyn Mayer
                     11:  *
                     12:  *   This program is free software; you can redistribute it and/or
                     13:  *   modify it under the terms of the GNU General Public License
                     14:  *   version 2
                     15:  *
                     16:  */
                     17: 
                     18: #include "config.h"
                     19: #include "libopenbios/bindings.h"
                     20: #include "kernel/kernel.h"
                     21: #include "drivers/pci.h"
                     22: #include "libc/byteorder.h"
                     23: #include "libc/vsprintf.h"
                     24: 
                     25: #include "drivers/drivers.h"
                     26: #include "drivers/vga.h"
                     27: #include "timer.h"
                     28: #include "pci.h"
                     29: #include "pci_database.h"
                     30: #ifdef CONFIG_DRIVER_MACIO
                     31: #include "cuda.h"
                     32: #include "macio.h"
                     33: #endif
                     34: 
                     35: #if defined (CONFIG_DEBUG_PCI)
                     36: # define PCI_DPRINTF(format, ...) printk(format, ## __VA_ARGS__)
                     37: #else
                     38: # define PCI_DPRINTF(format, ...) do { } while (0)
                     39: #endif
                     40: 
                     41: #define set_bool_property(ph, name) set_property(ph, name, NULL, 0);
                     42: 
                     43: /* DECLARE data structures for the nodes.  */
                     44: 
                     45: DECLARE_UNNAMED_NODE( ob_pci_bus_node, INSTALL_OPEN, 2*sizeof(int) );
                     46: DECLARE_UNNAMED_NODE( ob_pci_simple_node, INSTALL_OPEN, 2*sizeof(int) );
                     47: 
                     48: const pci_arch_t *arch;
                     49: 
                     50: #define IS_NOT_RELOCATABLE     0x80000000
                     51: #define IS_PREFETCHABLE                0x40000000
                     52: #define IS_ALIASED             0x20000000
                     53: 
                     54: enum {
                     55:        CONFIGURATION_SPACE = 0,
                     56:        IO_SPACE = 1,
                     57:        MEMORY_SPACE_32 = 2,
                     58:        MEMORY_SPACE_64 = 3,
                     59: };
                     60: 
                     61: static int encode_int32_cells(int num_cells, u32 *prop, ucell val)
                     62: {
                     63:     int i = 0;
                     64: 
                     65:     /* hi ... lo */
                     66:     for (i=0; i < num_cells; ++i) {
                     67:         prop[num_cells - i - 1] = val;
                     68:         val >>= 16;
                     69:         val >>= 16;
                     70:     }
                     71: 
                     72:     return num_cells;
                     73: }
                     74: 
                     75: static inline int pci_encode_phys_addr(u32 *phys, int flags, int space_code,
                     76:                                 pci_addr dev, uint8_t reg, uint64_t addr)
                     77: {
                     78: 
                     79:        /* phys.hi */
                     80: 
                     81:        phys[0] = flags | (space_code << 24) | dev | reg;
                     82: 
                     83:        /* phys.mid */
                     84: 
                     85:        phys[1] = addr >> 32;
                     86: 
                     87:        /* phys.lo */
                     88: 
                     89:        phys[2] = addr;
                     90: 
                     91:        return 3;
                     92: }
                     93: 
                     94: static inline int pci_encode_size(u32 *prop, uint64_t size)
                     95: {
                     96:     return encode_int32_cells(2, prop, size);
                     97: }
                     98: 
                     99: static int host_address_cells(void)
                    100: {
                    101:     return get_int_property(find_dev("/"), "#address-cells", NULL);
                    102: }
                    103: 
                    104: static int host_encode_phys_addr(u32 *prop, ucell addr)
                    105: {
                    106:     return encode_int32_cells(host_address_cells(), prop, addr);
                    107: }
                    108: 
                    109: static int host_size_cells(void)
                    110: {
                    111:     return get_int_property(find_dev("/"), "#size-cells", NULL);
                    112: }
                    113: 
                    114: /*
                    115: static int parent_address_cells(void)
                    116: {
                    117:     phandle_t parent_ph = ih_to_phandle(my_parent());
                    118:     return get_int_property(parent_ph, "#address-cells", NULL);
                    119: }
                    120: 
                    121: static int parent_size_cells(void)
                    122: {
                    123:     phandle_t parent_ph = ih_to_phandle(my_parent());
                    124:     return get_int_property(parent_ph, "#size-cells", NULL);
                    125: }
                    126: */
                    127: 
                    128: #if defined(CONFIG_DEBUG_PCI)
                    129: static void dump_reg_property(const char* description, int nreg, u32 *reg)
                    130: {
                    131:     int i;
                    132:     printk("%s reg", description);
                    133:     for (i=0; i < nreg; ++i) {
                    134:         printk(" %08X", reg[i]);
                    135:     }
                    136:     printk("\n");
                    137: }
                    138: #endif
                    139: 
                    140: static void
                    141: ob_pci_open(int *idx)
                    142: {
                    143:        int ret=1;
                    144:        RET ( -ret );
                    145: }
                    146: 
                    147: static void
                    148: ob_pci_close(int *idx)
                    149: {
                    150: }
                    151: 
                    152: static void
                    153: ob_pci_initialize(int *idx)
                    154: {
                    155: }
                    156: 
                    157: /* ( str len -- phys.lo phys.mid phys.hi ) */
                    158: 
                    159: static void
                    160: ob_pci_decode_unit(int *idx)
                    161: {
                    162:        ucell hi, mid, lo;
                    163:        const char *arg = pop_fstr_copy();
                    164:        int dev, fn, reg, ss, n, p, t;
                    165:        int bus = 0;            /* no information */
                    166:        char *ptr;
                    167: 
                    168:        PCI_DPRINTF("ob_pci_decode_unit idx=%p\n", idx);
                    169: 
                    170:        fn = 0;
                    171:        reg = 0;
                    172:        n = 0;
                    173:        p = 0;
                    174:        t = 0;
                    175: 
                    176:        ptr = (char*)arg;
                    177:        if (*ptr == 'n') {
                    178:                n = IS_NOT_RELOCATABLE;
                    179:                ptr++;
                    180:        }
                    181:        if (*ptr == 'i') {
                    182:                ss = IO_SPACE;
                    183:                ptr++;
                    184:                if (*ptr == 't') {
                    185:                        t = IS_ALIASED;
                    186:                        ptr++;
                    187:                }
                    188: 
                    189:                /* DD,F,RR,NNNNNNNN */
                    190: 
                    191:                dev = strtol(ptr, &ptr, 16);
                    192:                ptr++;
                    193:                fn = strtol(ptr, &ptr, 16);
                    194:                ptr++;
                    195:                reg = strtol(ptr, &ptr, 16);
                    196:                ptr++;
                    197:                lo = strtol(ptr, &ptr, 16);
                    198:                mid = 0;
                    199: 
                    200:        } else if (*ptr == 'm') {
                    201:                ss = MEMORY_SPACE_32;
                    202:                ptr++;
                    203:                if (*ptr == 't') {
                    204:                        t = IS_ALIASED;
                    205:                        ptr++;
                    206:                }
                    207:                if (*ptr == 'p') {
                    208:                        p = IS_PREFETCHABLE;
                    209:                        ptr++;
                    210:                }
                    211: 
                    212:                /* DD,F,RR,NNNNNNNN */
                    213: 
                    214:                dev = strtol(ptr, &ptr, 16);
                    215:                ptr++;
                    216:                fn = strtol(ptr, &ptr, 16);
                    217:                ptr++;
                    218:                reg = strtol(ptr, &ptr, 16);
                    219:                ptr++;
                    220:                lo = strtol(ptr, &ptr, 16);
                    221:                mid = 0;
                    222: 
                    223:        } else if (*ptr == 'x') {
                    224:                unsigned long long addr64;
                    225:                ss = MEMORY_SPACE_64;
                    226:                ptr++;
                    227:                if (*ptr == 'p') {
                    228:                        p = IS_PREFETCHABLE;
                    229:                        ptr++;
                    230:                }
                    231: 
                    232:                /* DD,F,RR,NNNNNNNNNNNNNNNN */
                    233: 
                    234:                dev = strtol(ptr, &ptr, 16);
                    235:                ptr++;
                    236:                fn = strtol(ptr, &ptr, 16);
                    237:                ptr++;
                    238:                reg = strtol(ptr, &ptr, 16);
                    239:                ptr++;
                    240:                addr64 = strtoll(ptr, &ptr, 16);
                    241:                lo = (ucell)addr64;
                    242:                mid = addr64 >> 32;
                    243: 
                    244:        } else {
                    245:                ss = CONFIGURATION_SPACE;
                    246:                /* "DD" or "DD,FF" */
                    247:                dev = strtol(ptr, &ptr, 16);
                    248:                if (*ptr == ',') {
                    249:                        ptr++;
                    250:                        fn = strtol(ptr, NULL, 16);
                    251:                }
                    252:                lo = 0;
                    253:                mid = 0;
                    254:        }
                    255:        free((char*)arg);
                    256: 
                    257:        hi = n | p | t | (ss << 24) | (bus << 16) | (dev << 11) | (fn << 8) | reg;
                    258: 
                    259:        PUSH(lo);
                    260:        PUSH(mid);
                    261:        PUSH(hi);
                    262: 
                    263:        PCI_DPRINTF("ob_pci_decode_unit idx=%p addr="
                    264:                FMT_ucellx " " FMT_ucellx " " FMT_ucellx "\n",
                    265:                idx, lo, mid, hi);
                    266: }
                    267: 
                    268: /*  ( phys.lo phy.mid phys.hi -- str len ) */
                    269: 
                    270: static void
                    271: ob_pci_encode_unit(int *idx)
                    272: {
                    273:        char buf[28];
                    274:        cell hi = POP();
                    275:        cell mid = POP();
                    276:        cell lo = POP();
                    277:         int n, p, t, ss, dev, fn, reg;
                    278: 
                    279:        n = hi & IS_NOT_RELOCATABLE;
                    280:        p = hi & IS_PREFETCHABLE;
                    281:        t = hi & IS_ALIASED;
                    282:        ss = (hi >> 24) & 0x03;
                    283: 
                    284:        dev = (hi >> 11) & 0x1F;
                    285:        fn = (hi >> 8) & 0x07;
                    286:        reg = hi & 0xFF;
                    287: 
                    288:        switch(ss) {
                    289:        case CONFIGURATION_SPACE:
                    290: 
                    291:                if (fn == 0)    /* DD */
                    292:                        snprintf(buf, sizeof(buf), "%x", dev);
                    293:                else            /* DD,F */
                    294:                        snprintf(buf, sizeof(buf), "%x,%x", dev, fn);
                    295:                break;
                    296: 
                    297:        case IO_SPACE:
                    298: 
                    299:                /* [n]i[t]DD,F,RR,NNNNNNNN */
                    300:                 snprintf(buf, sizeof(buf), "%si%s%x,%x,%x," FMT_ucellx,
                    301:                         n ? "n" : "",  /* relocatable */
                    302:                         t ? "t" : "",  /* aliased */
                    303:                         dev, fn, reg, t ? lo & 0x03FF : lo);
                    304:                break;
                    305: 
                    306:        case MEMORY_SPACE_32:
                    307: 
                    308:                /* [n]m[t][p]DD,F,RR,NNNNNNNN */
                    309:                 snprintf(buf, sizeof(buf), "%sm%s%s%x,%x,%x," FMT_ucellx,
                    310:                         n ? "n" : "",  /* relocatable */
                    311:                         t ? "t" : "",  /* aliased */
                    312:                         p ? "p" : "",  /* prefetchable */
                    313:                         dev, fn, reg, lo );
                    314:                break;
                    315: 
                    316:        case MEMORY_SPACE_64:
                    317: 
                    318:                /* [n]x[p]DD,F,RR,NNNNNNNNNNNNNNNN */
                    319:                snprintf(buf, sizeof(buf), "%sx%s%x,%x,%x,%llx",
                    320:                         n ? "n" : "",  /* relocatable */
                    321:                         p ? "p" : "",  /* prefetchable */
                    322:                          dev, fn, reg, ((long long)mid << 32) | (long long)lo);
                    323:                break;
                    324:        }
                    325:        push_str(buf);
                    326: 
                    327:        PCI_DPRINTF("ob_pci_encode_unit space=%d dev=%d fn=%d buf=%s\n",
                    328:                ss, dev, fn, buf);
                    329: }
                    330: 
                    331: NODE_METHODS(ob_pci_bus_node) = {
                    332:        { NULL,                 ob_pci_initialize       },
                    333:        { "open",               ob_pci_open             },
                    334:        { "close",              ob_pci_close            },
                    335:        { "decode-unit",        ob_pci_decode_unit      },
                    336:        { "encode-unit",        ob_pci_encode_unit      },
                    337: };
                    338: 
                    339: NODE_METHODS(ob_pci_simple_node) = {
                    340:        { NULL,                 ob_pci_initialize       },
                    341:        { "open",               ob_pci_open             },
                    342:        { "close",              ob_pci_close            },
                    343: };
                    344: 
                    345: static void pci_set_bus_range(const pci_config_t *config)
                    346: {
                    347:        phandle_t dev = find_dev(config->path);
                    348:        u32 props[2];
                    349: 
                    350:        props[0] = config->secondary_bus;
                    351:        props[1] = config->subordinate_bus;
                    352: 
                    353:        PCI_DPRINTF("setting bus range for %s PCI device, "
                    354:                "package handle " FMT_ucellx " "
                    355:             "bus primary=%d secondary=%d subordinate=%d\n",
                    356:             config->path,
                    357:             dev,
                    358:             config->primary_bus,
                    359:             config->secondary_bus,
                    360:             config->subordinate_bus);
                    361: 
                    362: 
                    363:        set_property(dev, "bus-range", (char *)props, 2 * sizeof(props[0]));
                    364: }
                    365: 
                    366: static void pci_host_set_interrupt_map(const pci_config_t *config)
                    367: {
                    368: /* XXX We currently have a hook in the MPIC init code to fill in its handle.
                    369:  *     If you want to have interrupt maps for your PCI host bus, add your
                    370:  *     architecture to the #if and make your bridge detect code fill in its
                    371:  *     handle too.
                    372:  *
                    373:  *     It would be great if someone clever could come up with a more universal
                    374:  *     mechanism here.
                    375:  */
                    376: #if defined(CONFIG_PPC)
                    377:        phandle_t dev = get_cur_dev();
                    378:        u32 props[7 * 4];
                    379:        int i;
                    380: 
                    381: #if defined(CONFIG_PPC)
                    382:        /* Oldworld macs do interrupt maps differently */
                    383:        if(!is_newworld())
                    384:                return;
                    385: #endif
                    386: 
                    387:        for (i = 0; i < (7*4); i+=7) {
                    388:                props[i+PCI_INT_MAP_PCI0] = 0;
                    389:                props[i+PCI_INT_MAP_PCI1] = 0;
                    390:                props[i+PCI_INT_MAP_PCI2] = 0;
                    391:                props[i+PCI_INT_MAP_PCI_INT] = (i / 7) + 1; // starts at PINA=1
                    392:                props[i+PCI_INT_MAP_PIC_HANDLE] = 0; // gets patched in later
                    393:                props[i+PCI_INT_MAP_PIC_INT] = arch->irqs[i / 7];
                    394:                props[i+PCI_INT_MAP_PIC_POL] = 3;
                    395:        }
                    396:        set_property(dev, "interrupt-map", (char *)props, 7 * 4 * sizeof(props[0]));
                    397: 
                    398:        props[PCI_INT_MAP_PCI0] = 0;
                    399:        props[PCI_INT_MAP_PCI1] = 0;
                    400:        props[PCI_INT_MAP_PCI2] = 0;
                    401:        props[PCI_INT_MAP_PCI_INT] = 0x7;
                    402: 
                    403:        set_property(dev, "interrupt-map-mask", (char *)props, 4 * sizeof(props[0]));
                    404: #endif
                    405: }
                    406: 
                    407: static void pci_host_set_reg(phandle_t phandle)
                    408: {
                    409:     phandle_t dev = phandle;
                    410: 
                    411:     /* at most 2 integers for address and size */
                    412:     u32 props[4];
                    413:     int ncells = 0;
                    414: 
                    415:     ncells += encode_int32_cells(host_address_cells(), props + ncells,
                    416:             arch->cfg_base);
                    417: 
                    418:     ncells += encode_int32_cells(host_size_cells(), props + ncells,
                    419:             arch->cfg_len);
                    420: 
                    421:     set_property(dev, "reg", (char *)props, ncells * sizeof(props[0]));
                    422: 
                    423: #if defined(CONFIG_DEBUG_PCI)
                    424:     dump_reg_property("pci_host_set_reg", 4, props);
                    425: #endif
                    426: }
                    427: 
                    428: /* child-phys : parent-phys : size */
                    429: /* 3 cells for PCI : 2 cells for 64bit parent : 2 cells for PCI */
                    430: 
                    431: static void pci_host_set_ranges(const pci_config_t *config)
                    432: {
                    433:        phandle_t dev = get_cur_dev();
                    434:        u32 props[32];
                    435:        int ncells;
                    436: 
                    437:        ncells = 0;
                    438:        /* first encode PCI configuration space */
                    439:        {
                    440:            ncells += pci_encode_phys_addr(props + ncells, 0, CONFIGURATION_SPACE,
                    441:                      config->dev, 0, 0);
                    442:         ncells += host_encode_phys_addr(props + ncells, arch->cfg_addr);
                    443:         ncells += pci_encode_size(props + ncells, arch->cfg_len);
                    444:        }
                    445: 
                    446:        if (arch->io_base) {
                    447:            ncells += pci_encode_phys_addr(props + ncells, 0, IO_SPACE,
                    448:                                     config->dev, 0, 0);
                    449:         ncells += host_encode_phys_addr(props + ncells, arch->io_base);
                    450:         ncells += pci_encode_size(props + ncells, arch->io_len);
                    451:        }
                    452:        if (arch->rbase) {
                    453:            ncells += pci_encode_phys_addr(props + ncells, 0, MEMORY_SPACE_32,
                    454:                                     config->dev, 0, 0);
                    455:         ncells += host_encode_phys_addr(props + ncells, arch->rbase);
                    456:         ncells += pci_encode_size(props + ncells, arch->rlen);
                    457:        }
                    458:        if (arch->host_mem_base) {
                    459:            ncells += pci_encode_phys_addr(props + ncells, 0, MEMORY_SPACE_32,
                    460:                                     config->dev, 0, arch->pci_mem_base);
                    461:         ncells += host_encode_phys_addr(props + ncells, arch->host_mem_base);
                    462:         ncells += pci_encode_size(props + ncells, arch->mem_len);
                    463:        }
                    464:        set_property(dev, "ranges", (char *)props, ncells * sizeof(props[0]));
                    465: }
                    466: 
                    467: static unsigned long pci_bus_addr_to_host_addr(uint32_t ba)
                    468: {
                    469: #ifdef CONFIG_SPARC64
                    470:     return arch->cfg_data + (unsigned long)ba;
                    471: #else
                    472:     return (unsigned long)ba;
                    473: #endif
                    474: }
                    475: 
                    476: int host_config_cb(const pci_config_t *config)
                    477: {
                    478:        //XXX this overrides "reg" property
                    479:        pci_host_set_reg(get_cur_dev());
                    480:        pci_host_set_ranges(config);
                    481:        pci_host_set_interrupt_map(config);
                    482: 
                    483:        return 0;
                    484: }
                    485: 
                    486: static int sabre_configure(phandle_t dev)
                    487: {
                    488:         uint32_t props[28];
                    489: 
                    490:         props[0] = 0xc0000000;
                    491:         props[1] = 0x20000000;
                    492:         set_property(dev, "virtual-dma", (char *)props, 2 * sizeof(props[0]));
                    493:         props[0] = 1;
                    494:         set_property(dev, "#virtual-dma-size-cells", (char *)props,
                    495:                      sizeof(props[0]));
                    496:         set_property(dev, "#virtual-dma-addr-cells", (char *)props,
                    497:                      sizeof(props[0]));
                    498:         props[0] = 0x000007f0;
                    499:         props[1] = 0x000007ee;
                    500:         props[2] = 0x000007ef;
                    501:         props[3] = 0x000007e5;
                    502:         set_property(dev, "interrupts", (char *)props, 4 * sizeof(props[0]));
                    503:         props[0] = 0x0000001f;
                    504:         set_property(dev, "upa-portid", (char *)props, 1 * sizeof(props[0]));
                    505:         return 0;
                    506: }
                    507: 
                    508: int sabre_config_cb(const pci_config_t *config)
                    509: {
                    510:     host_config_cb(config);
                    511: 
                    512:     return sabre_configure(get_cur_dev());
                    513: }
                    514: 
                    515: int bridge_config_cb(const pci_config_t *config)
                    516: {
                    517:        phandle_t aliases;
                    518: 
                    519:        aliases = find_dev("/aliases");
                    520:        set_property(aliases, "bridge", config->path, strlen(config->path) + 1);
                    521: 
                    522:        return 0;
                    523: }
                    524: 
                    525: int ide_config_cb2 (const pci_config_t *config)
                    526: {
                    527:        ob_ide_init(config->path,
                    528:                    config->assigned[0] & ~0x0000000F,
                    529:                    config->assigned[1] & ~0x0000000F,
                    530:                    config->assigned[2] & ~0x0000000F,
                    531:                    config->assigned[3] & ~0x0000000F);
                    532:        return 0;
                    533: }
                    534: 
                    535: int eth_config_cb (const pci_config_t *config)
                    536: {
                    537:        phandle_t ph = get_cur_dev();
                    538: 
                    539:        set_property(ph, "network-type", "ethernet", 9);
                    540:        set_property(ph, "removable", "network", 8);
                    541:        set_property(ph, "category", "net", 4);
                    542: 
                    543:         return 0;
                    544: }
                    545: 
                    546: static inline void pci_decode_pci_addr(pci_addr addr, int *flags,
                    547:                                       int *space_code, uint32_t *mask)
                    548: {
                    549:     *flags = 0;
                    550: 
                    551:        if (addr & 0x01) {
                    552:                *space_code = IO_SPACE;
                    553:                *mask = 0x00000001;
                    554:        } else {
                    555:            if (addr & 0x04) {
                    556:             *space_code = MEMORY_SPACE_64;
                    557:             *flags |= IS_NOT_RELOCATABLE; /* XXX: why not relocatable? */
                    558:         } else {
                    559:             *space_code = MEMORY_SPACE_32;
                    560:         }
                    561: 
                    562:         if (addr & 0x08) {
                    563:             *flags |= IS_PREFETCHABLE;
                    564:         }
                    565: 
                    566:         *mask = 0x0000000F;
                    567:        }
                    568: }
                    569: 
                    570: /*
                    571:  * "Designing PCI Cards and Drivers for Power Macintosh Computers", p. 454
                    572:  *
                    573:  *  "AAPL,address" provides an array of 32-bit logical addresses
                    574:  *  Nth entry corresponding to Nth "assigned-address" base address entry.
                    575:  */
                    576: 
                    577: static void pci_set_AAPL_address(const pci_config_t *config)
                    578: {
                    579:        phandle_t dev = get_cur_dev();
                    580:        cell props[7];
                    581:        int ncells, i;
                    582: 
                    583:        ncells = 0;
                    584:        for (i = 0; i < 6; i++) {
                    585:                if (!config->assigned[i] || !config->sizes[i])
                    586:                        continue;
                    587:                props[ncells++] = config->assigned[i] & ~0x0000000F;
                    588:        }
                    589:        if (ncells)
                    590:                set_property(dev, "AAPL,address", (char *)props,
                    591:                             ncells * sizeof(cell));
                    592: }
                    593: 
                    594: static void pci_set_assigned_addresses(phandle_t phandle,
                    595:                                        const pci_config_t *config, int num_bars)
                    596: {
                    597:        phandle_t dev = phandle;
                    598:        u32 props[32];
                    599:        int ncells;
                    600:        int i;
                    601:        uint32_t mask;
                    602:        int flags, space_code;
                    603: 
                    604:        ncells = 0;
                    605:        for (i = 0; i < num_bars; i++) {
                    606:                /* consider only bars with non-zero region size */
                    607:                if (!config->sizes[i])
                    608:                        continue;
                    609:                pci_decode_pci_addr(config->assigned[i],
                    610:                                    &flags, &space_code, &mask);
                    611: 
                    612:                ncells += pci_encode_phys_addr(props + ncells,
                    613:                                     flags, space_code, config->dev,
                    614:                                     PCI_BASE_ADDR_0 + (i * sizeof(uint32_t)),
                    615:                                     config->assigned[i] & ~mask);
                    616: 
                    617:                props[ncells++] = 0x00000000;
                    618:                props[ncells++] = config->sizes[i];
                    619:        }
                    620:        if (ncells)
                    621:                set_property(dev, "assigned-addresses", (char *)props,
                    622:                             ncells * sizeof(props[0]));
                    623: }
                    624: 
                    625: /* call after writing "reg" property to update config->path */
                    626: static void ob_pci_reload_device_path(phandle_t phandle, pci_config_t *config)
                    627: {
                    628:     /* since "name" and "reg" are now assigned
                    629:        we need to reload current node name */
                    630: 
                    631:     PUSH(phandle);
                    632:     fword("get-package-path");
                    633:     char *new_path = pop_fstr_copy();
                    634:     if (new_path) {
                    635:         if (0 != strcmp(config->path, new_path)) {
                    636:             PCI_DPRINTF("\n=== CHANGED === package path old=%s new=%s\n",
                    637:                     config->path, new_path);
                    638:             strncpy(config->path, new_path, sizeof(config->path));
                    639:             config->path[sizeof(config->path)-1] = '\0';
                    640:         }
                    641:         free(new_path);
                    642:     } else {
                    643:         PCI_DPRINTF("\n=== package path old=%s new=NULL\n", config->path);
                    644:     }
                    645: }
                    646: 
                    647: static void pci_set_reg(phandle_t phandle,
                    648:                         pci_config_t *config, int num_bars)
                    649: {
                    650:        phandle_t dev = phandle;
                    651:        u32 props[38];
                    652:        int ncells;
                    653:        int i;
                    654:        uint32_t mask;
                    655:        int space_code, flags;
                    656: 
                    657:     ncells = 0;
                    658: 
                    659:     /* first (addr, size) pair is the beginning of configuration address space */
                    660:        ncells += pci_encode_phys_addr(props + ncells, 0, CONFIGURATION_SPACE,
                    661:                             config->dev, 0, 0);
                    662: 
                    663:        ncells += pci_encode_size(props + ncells, 0);
                    664: 
                    665:        for (i = 0; i < num_bars; i++) {
                    666:                /* consider only bars with non-zero region size */
                    667:                if (!config->sizes[i])
                    668:                        continue;
                    669: 
                    670:                pci_decode_pci_addr(config->regions[i],
                    671:                                    &flags, &space_code, &mask);
                    672: 
                    673:                ncells += pci_encode_phys_addr(props + ncells,
                    674:                                     flags, space_code, config->dev,
                    675:                                     PCI_BASE_ADDR_0 + (i * sizeof(uint32_t)),
                    676:                                     config->regions[i] & ~mask);
                    677: 
                    678:                /* set size */
                    679:                ncells += pci_encode_size(props + ncells, config->sizes[i]);
                    680:        }
                    681: 
                    682:        set_property(dev, "reg", (char *)props, ncells * sizeof(props[0]));
                    683:     ob_pci_reload_device_path(dev, config);
                    684: 
                    685: #if defined(CONFIG_DEBUG_PCI)
                    686:     dump_reg_property("pci_set_reg", ncells, props);
                    687: #endif
                    688: }
                    689: 
                    690: 
                    691: static void pci_set_ranges(const pci_config_t *config)
                    692: {
                    693:        phandle_t dev = get_cur_dev();
                    694:        u32 props[32];
                    695:        int ncells;
                    696:        int i;
                    697:        uint32_t mask;
                    698:        int flags;
                    699:        int space_code;
                    700: 
                    701:        ncells = 0;
                    702:        for (i = 0; i < 6; i++) {
                    703:                if (!config->assigned[i] || !config->sizes[i])
                    704:                        continue;
                    705: 
                    706:                /* child address */
                    707: 
                    708:                props[ncells++] = 0x00000000;
                    709: 
                    710:                /* parent address */
                    711: 
                    712:                pci_decode_pci_addr(config->assigned[i],
                    713:                                    &flags, &space_code, &mask);
                    714:                ncells += pci_encode_phys_addr(props + ncells, flags, space_code,
                    715:                                     config->dev, 0x10 + i * 4,
                    716:                                     config->assigned[i] & ~mask);
                    717: 
                    718:                /* size */
                    719: 
                    720:                props[ncells++] = config->sizes[i];
                    721:        }
                    722:        set_property(dev, "ranges", (char *)props, ncells * sizeof(props[0]));
                    723: }
                    724: 
                    725: int macio_heathrow_config_cb (const pci_config_t *config)
                    726: {
                    727:        pci_set_ranges(config);
                    728: 
                    729: #ifdef CONFIG_DRIVER_MACIO
                    730:         ob_macio_heathrow_init(config->path, config->assigned[0] & ~0x0000000F);
                    731: #endif
                    732:        return 0;
                    733: }
                    734: 
                    735: int macio_keylargo_config_cb (const pci_config_t *config)
                    736: {
                    737:         pci_set_ranges(config);
                    738: 
                    739: #ifdef CONFIG_DRIVER_MACIO
                    740:         ob_macio_keylargo_init(config->path, config->assigned[0] & ~0x0000000F);
                    741: #endif
                    742:         return 0;
                    743: }
                    744: 
                    745: int vga_config_cb (const pci_config_t *config)
                    746: {
                    747:        if (config->assigned[0] != 0x00000000)
                    748:             vga_vbe_init(config->path,
                    749:                          pci_bus_addr_to_host_addr(config->assigned[0] & ~0x0000000F),
                    750:                          config->sizes[0],
                    751:                          pci_bus_addr_to_host_addr(config->assigned[1] & ~0x0000000F),
                    752:                          config->sizes[1]);
                    753:        return 0;
                    754: }
                    755: 
                    756: int ebus_config_cb(const pci_config_t *config)
                    757: {
                    758: #ifdef CONFIG_DRIVER_EBUS
                    759: #ifdef CONFIG_DRIVER_FLOPPY
                    760:     ob_floppy_init(config->path, "fdthree", 0x3f0ULL, 0);
                    761: #endif
                    762: #ifdef CONFIG_DRIVER_PC_SERIAL
                    763:     ob_pc_serial_init(config->path, "su", arch->io_base, 0x3f8ULL, 0);
                    764: #endif
                    765: #ifdef CONFIG_DRIVER_PC_KBD
                    766:     ob_pc_kbd_init(config->path, "kb_ps2", arch->io_base, 0x60ULL, 0);
                    767: #endif
                    768: #endif
                    769:     return 0;
                    770: }
                    771: 
                    772: static void ob_pci_add_properties(phandle_t phandle,
                    773:                                   pci_addr addr, const pci_dev_t *pci_dev,
                    774:                                   const pci_config_t *config, int num_bars)
                    775: {
                    776:        /* cannot use get_cur_dev() path resolution since "name" and "reg"
                    777:           properties are being changed */
                    778:        phandle_t dev=phandle;
                    779:        int status,id;
                    780:        uint16_t vendor_id, device_id;
                    781:        uint8_t rev;
                    782:        uint32_t class_code;
                    783: 
                    784:        vendor_id = pci_config_read16(addr, PCI_VENDOR_ID);
                    785:        device_id = pci_config_read16(addr, PCI_DEVICE_ID);
                    786:        rev = pci_config_read8(addr, PCI_REVISION_ID);
                    787:        class_code = pci_config_read16(addr, PCI_CLASS_DEVICE);
                    788: 
                    789:     if (pci_dev) {
                    790:         /**/
                    791:         if (pci_dev->name) {
                    792:             push_str(pci_dev->name);
                    793:             fword("encode-string");
                    794:             push_str("name");
                    795:             fword("property");
                    796:         } else {
                    797:             char path[256];
                    798:             snprintf(path, sizeof(path),
                    799:                     "pci%x,%x", vendor_id, device_id);
                    800:             push_str(path);
                    801:             fword("encode-string");
                    802:             push_str("name");
                    803:             fword("property");
                    804:         }
                    805:     } else {
                    806:         PCI_DPRINTF("*** missing pci_dev\n");
                    807:     }
                    808: 
                    809:        /* create properties as described in 2.5 */
                    810: 
                    811:        set_int_property(dev, "vendor-id", vendor_id);
                    812:        set_int_property(dev, "device-id", device_id);
                    813:        set_int_property(dev, "revision-id", rev);
                    814:        set_int_property(dev, "class-code", class_code << 8);
                    815: 
                    816:        if (config->irq_pin) {
                    817:                OLDWORLD(set_int_property(dev, "AAPL,interrupts",
                    818:                                          config->irq_line));
                    819:                set_int_property(dev, "interrupts", config->irq_pin);
                    820:        }
                    821: 
                    822:        set_int_property(dev, "min-grant", pci_config_read8(addr, PCI_MIN_GNT));
                    823:        set_int_property(dev, "max-latency", pci_config_read8(addr, PCI_MAX_LAT));
                    824: 
                    825:        status=pci_config_read16(addr, PCI_STATUS);
                    826: 
                    827:        set_int_property(dev, "devsel-speed",
                    828:                        (status&PCI_STATUS_DEVSEL_MASK)>>10);
                    829: 
                    830:        if(status&PCI_STATUS_FAST_BACK)
                    831:                set_bool_property(dev, "fast-back-to-back");
                    832:        if(status&PCI_STATUS_66MHZ)
                    833:                set_bool_property(dev, "66mhz-capable");
                    834:        if(status&PCI_STATUS_UDF)
                    835:                set_bool_property(dev, "udf-supported");
                    836: 
                    837:        id=pci_config_read16(addr, PCI_SUBSYSTEM_VENDOR_ID);
                    838:        if(id)
                    839:                set_int_property(dev, "subsystem-vendor-id", id);
                    840:        id=pci_config_read16(addr, PCI_SUBSYSTEM_ID);
                    841:        if(id)
                    842:                set_int_property(dev, "subsystem-id", id);
                    843: 
                    844:        set_int_property(dev, "cache-line-size",
                    845:                        pci_config_read16(addr, PCI_CACHE_LINE_SIZE));
                    846: 
                    847:        if (pci_dev) {
                    848:                if (pci_dev->type) {
                    849:                        push_str(pci_dev->type);
                    850:                        fword("encode-string");
                    851:                        push_str("device_type");
                    852:                        fword("property");
                    853:                }
                    854:                if (pci_dev->model) {
                    855:                        push_str(pci_dev->model);
                    856:                        fword("encode-string");
                    857:                        push_str("model");
                    858:                        fword("property");
                    859:                }
                    860:                if (pci_dev->compat)
                    861:                        set_property(dev, "compatible",
                    862:                                     pci_dev->compat, pci_compat_len(pci_dev));
                    863: 
                    864:                if (pci_dev->acells)
                    865:                        set_int_property(dev, "#address-cells",
                    866:                                              pci_dev->acells);
                    867:                if (pci_dev->scells)
                    868:                        set_int_property(dev, "#size-cells",
                    869:                                               pci_dev->scells);
                    870:                if (pci_dev->icells)
                    871:                        set_int_property(dev, "#interrupt-cells",
                    872:                                              pci_dev->icells);
                    873:        }
                    874: 
                    875:        pci_set_assigned_addresses(phandle, config, num_bars);
                    876:        OLDWORLD(pci_set_AAPL_address(config));
                    877: 
                    878:        PCI_DPRINTF("\n");
                    879: }
                    880: 
                    881: #ifdef CONFIG_XBOX
                    882: static char pci_xbox_blacklisted (int bus, int devnum, int fn)
                    883: {
                    884:        /*
                    885:         * The Xbox MCPX chipset is a derivative of the nForce 1
                    886:         * chipset. It almost has the same bus layout; some devices
                    887:         * cannot be used, because they have been removed.
                    888:         */
                    889: 
                    890:        /*
                    891:         * Devices 00:00.1 and 00:00.2 used to be memory controllers on
                    892:         * the nForce chipset, but on the Xbox, using them will lockup
                    893:         * the chipset.
                    894:         */
                    895:        if ((bus == 0) && (devnum == 0) && ((fn == 1) || (fn == 2)))
                    896:                return 1;
                    897: 
                    898:        /*
                    899:         * Bus 1 only contains a VGA controller at 01:00.0. When you try
                    900:         * to probe beyond that device, you only get garbage, which
                    901:         * could cause lockups.
                    902:         */
                    903:        if ((bus == 1) && ((devnum != 0) || (fn != 0)))
                    904:                return 1;
                    905: 
                    906:        /*
                    907:         * Bus 2 used to contain the AGP controller, but the Xbox MCPX
                    908:         * doesn't have one. Probing it can cause lockups.
                    909:         */
                    910:        if (bus >= 2)
                    911:                return 1;
                    912: 
                    913:        /*
                    914:         * The device is not blacklisted.
                    915:         */
                    916:        return 0;
                    917: }
                    918: #endif
                    919: 
                    920: static void ob_pci_configure_bar(pci_addr addr, pci_config_t *config,
                    921:                                  int reg, int config_addr,
                    922:                                  uint32_t *p_omask,
                    923:                                  unsigned long *mem_base,
                    924:                                  unsigned long *io_base)
                    925: {
                    926:         uint32_t smask, amask, size, reloc, min_align;
                    927:         unsigned long base;
                    928: 
                    929:         config->assigned[reg] = 0x00000000;
                    930:         config->sizes[reg] = 0x00000000;
                    931: 
                    932:         if ((*p_omask & 0x0000000f) == 0x4) {
                    933:                 /* 64 bits memory mapping */
                    934:                 return;
                    935:         }
                    936: 
                    937:         config->regions[reg] = pci_config_read32(addr, config_addr);
                    938: 
                    939:         /* get region size */
                    940: 
                    941:         pci_config_write32(addr, config_addr, 0xffffffff);
                    942:         smask = pci_config_read32(addr, config_addr);
                    943:         if (smask == 0x00000000 || smask == 0xffffffff)
                    944:                 return;
                    945: 
                    946:         if (smask & 0x00000001 && reg != 6) {
                    947:                 /* I/O space */
                    948:                 base = *io_base;
                    949:                 min_align = 1 << 7;
                    950:                 amask = 0x00000001;
                    951:         } else {
                    952:                 /* Memory Space */
                    953:                 base = *mem_base;
                    954:                 min_align = 1 << 16;
                    955:                 amask = 0x0000000F;
                    956:                 if (reg == 6) {
                    957:                         smask |= 1; /* ROM */
                    958:                 }
                    959:         }
                    960:         *p_omask = smask & amask;
                    961:         smask &= ~amask;
                    962:         size = (~smask) + 1;
                    963:         config->sizes[reg] = size;
                    964:         reloc = base;
                    965:         if (size < min_align)
                    966:                 size = min_align;
                    967:         reloc = (reloc + size -1) & ~(size - 1);
                    968:         if (*io_base == base) {
                    969:                 *io_base = reloc + size;
                    970:                 reloc -= arch->io_base;
                    971:         } else {
                    972:                 *mem_base = reloc + size;
                    973:         }
                    974:         pci_config_write32(addr, config_addr, reloc | *p_omask);
                    975:         config->assigned[reg] = reloc | *p_omask;
                    976: }
                    977: 
                    978: static void ob_pci_configure_irq(pci_addr addr, pci_config_t *config)
                    979: {
                    980:         uint8_t irq_pin, irq_line;
                    981: 
                    982:         irq_pin =  pci_config_read8(addr, PCI_INTERRUPT_PIN);
                    983:         if (irq_pin) {
                    984:                 config->irq_pin = irq_pin;
                    985:                 irq_pin = (((config->dev >> 11) & 0x1F) + irq_pin - 1) & 3;
                    986:                 irq_line = arch->irqs[irq_pin];
                    987:                 pci_config_write8(addr, PCI_INTERRUPT_LINE, irq_line);
                    988:                 config->irq_line = irq_line;
                    989:         } else
                    990:                 config->irq_line = -1;
                    991: }
                    992: 
                    993: static void
                    994: ob_pci_configure(pci_addr addr, pci_config_t *config, int num_regs, int rom_bar,
                    995:                  unsigned long *mem_base, unsigned long *io_base)
                    996: 
                    997: {
                    998:         uint32_t omask;
                    999:         uint16_t cmd;
                   1000:         int reg;
                   1001:         pci_addr config_addr;
                   1002: 
                   1003:         ob_pci_configure_irq(addr, config);
                   1004: 
                   1005:         omask = 0x00000000;
                   1006:         for (reg = 0; reg < num_regs; ++reg) {
                   1007:                 config_addr = PCI_BASE_ADDR_0 + reg * 4;
                   1008: 
                   1009:                 ob_pci_configure_bar(addr, config, reg, config_addr,
                   1010:                                      &omask, mem_base,
                   1011:                                      io_base);
                   1012:         }
                   1013: 
                   1014:         if (rom_bar) {
                   1015:                 config_addr = rom_bar;
                   1016:                 ob_pci_configure_bar(addr, config, reg, config_addr,
                   1017:                                      &omask, mem_base, io_base);
                   1018:         }
                   1019:         cmd = pci_config_read16(addr, PCI_COMMAND);
                   1020:         cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
                   1021:         pci_config_write16(addr, PCI_COMMAND, cmd);
                   1022: }
                   1023: 
                   1024: static void ob_configure_pci_device(const char* parent_path,
                   1025:         int *bus_num, unsigned long *mem_base, unsigned long *io_base,
                   1026:         int bus, int devnum, int fn, int *p_is_multi);
                   1027: 
                   1028: static void ob_scan_pci_bus(int *bus_num, unsigned long *mem_base,
                   1029:                             unsigned long *io_base, const char *path,
                   1030:                             int bus)
                   1031: {
                   1032:        int devnum, fn, is_multi;
                   1033: 
                   1034:        PCI_DPRINTF("\nScanning bus %d at %s...\n", bus, path);
                   1035: 
                   1036:        for (devnum = 0; devnum < 32; devnum++) {
                   1037:                is_multi = 0;
                   1038:                for (fn = 0; fn==0 || (is_multi && fn<8); fn++) {
                   1039:                    ob_configure_pci_device(path, bus_num, mem_base, io_base,
                   1040:                            bus, devnum, fn, &is_multi);
                   1041: 
                   1042:                }
                   1043:        }
                   1044: }
                   1045: 
                   1046: static void ob_configure_pci_bridge(pci_addr addr,
                   1047:                                     int *bus_num, unsigned long *mem_base,
                   1048:                                     unsigned long *io_base,
                   1049:                                     int primary_bus, pci_config_t *config)
                   1050: {
                   1051:     config->primary_bus = primary_bus;
                   1052:     pci_config_write8(addr, PCI_PRIMARY_BUS, config->primary_bus);
                   1053: 
                   1054:     config->secondary_bus = *bus_num;
                   1055:     pci_config_write8(addr, PCI_SECONDARY_BUS, config->secondary_bus);
                   1056: 
                   1057:     config->subordinate_bus = 0xff;
                   1058:     pci_config_write8(addr, PCI_SUBORDINATE_BUS, config->subordinate_bus);
                   1059: 
                   1060:     PCI_DPRINTF("scanning new pci bus %u under bridge %s\n",
                   1061:             config->secondary_bus, config->path);
                   1062: 
                   1063:     /* make pci bridge parent device, prepare for recursion */
                   1064: 
                   1065:     ob_scan_pci_bus(bus_num, mem_base, io_base,
                   1066:                     config->path, config->secondary_bus);
                   1067: 
                   1068:     /* bus scan updates *bus_num to last revealed pci bus number */
                   1069:     config->subordinate_bus = *bus_num;
                   1070:     pci_config_write8(addr, PCI_SUBORDINATE_BUS, config->subordinate_bus);
                   1071: 
                   1072:     PCI_DPRINTF("bridge %s PCI bus primary=%d secondary=%d subordinate=%d\n",
                   1073:             config->path, config->primary_bus, config->secondary_bus,
                   1074:             config->subordinate_bus);
                   1075: 
                   1076:     pci_set_bus_range(config);
                   1077: }
                   1078: 
                   1079: static int ob_pci_read_identification(int bus, int devnum, int fn,
                   1080:                                  int *p_vid, int *p_did,
                   1081:                                  uint8_t *p_class, uint8_t *p_subclass)
                   1082: {
                   1083:     int vid, did;
                   1084:     uint32_t ccode;
                   1085:     pci_addr addr;
                   1086: 
                   1087: #ifdef CONFIG_XBOX
                   1088:     if (pci_xbox_blacklisted (bus, devnum, fn))
                   1089:         return;
                   1090: #endif
                   1091:     addr = PCI_ADDR(bus, devnum, fn);
                   1092:     vid = pci_config_read16(addr, PCI_VENDOR_ID);
                   1093:     did = pci_config_read16(addr, PCI_DEVICE_ID);
                   1094: 
                   1095:     if (vid==0xffff || vid==0) {
                   1096:         return 0;
                   1097:     }
                   1098: 
                   1099:     if (p_vid) {
                   1100:         *p_vid = vid;
                   1101:     }
                   1102: 
                   1103:     if (p_did) {
                   1104:         *p_did = did;
                   1105:     }
                   1106: 
                   1107:     ccode = pci_config_read16(addr, PCI_CLASS_DEVICE);
                   1108: 
                   1109:     if (p_class) {
                   1110:         *p_class = ccode >> 8;
                   1111:     }
                   1112: 
                   1113:     if (p_subclass) {
                   1114:         *p_subclass = ccode;
                   1115:     }
                   1116: 
                   1117:     return 1;
                   1118: }
                   1119: 
                   1120: static void ob_configure_pci_device(const char* parent_path,
                   1121:         int *bus_num, unsigned long *mem_base, unsigned long *io_base,
                   1122:         int bus, int devnum, int fn, int *p_is_multi)
                   1123: {
                   1124:     int vid, did;
                   1125:     unsigned int htype;
                   1126:     pci_addr addr;
                   1127:     pci_config_t config = {};
                   1128:         const pci_dev_t *pci_dev;
                   1129:     uint8_t class, subclass, iface;
                   1130:     int num_bars, rom_bar;
                   1131: 
                   1132:     phandle_t phandle = 0;
                   1133:     int is_host_bridge = 0;
                   1134: 
                   1135:     if (!ob_pci_read_identification(bus, devnum, fn, &vid, &did, &class, &subclass)) {
                   1136:         return;
                   1137:     }
                   1138: 
                   1139:     addr = PCI_ADDR(bus, devnum, fn);
                   1140:     iface = pci_config_read8(addr, PCI_CLASS_PROG);
                   1141: 
                   1142:     pci_dev = pci_find_device(class, subclass, iface,
                   1143:                   vid, did);
                   1144: 
                   1145:     PCI_DPRINTF("%x:%x.%x - %x:%x - ", bus, devnum, fn,
                   1146:             vid, did);
                   1147: 
                   1148:     htype = pci_config_read8(addr, PCI_HEADER_TYPE);
                   1149: 
                   1150:     if (fn == 0) {
                   1151:         if (p_is_multi) {
                   1152:             *p_is_multi = htype & 0x80;
                   1153:         }
                   1154:     }
                   1155: 
                   1156:     /* stop adding host bridge accessible from it's primary bus
                   1157:        PCI host bridge is to be added by host code
                   1158:     */
                   1159:     if (class == PCI_BASE_CLASS_BRIDGE &&
                   1160:             subclass == PCI_SUBCLASS_BRIDGE_HOST) {
                   1161:         is_host_bridge = 1;
                   1162:     }
                   1163: 
                   1164:     if (is_host_bridge) {
                   1165:         /* reuse device tree node */
                   1166:         PCI_DPRINTF("host bridge found - ");
                   1167:         snprintf(config.path, sizeof(config.path),
                   1168:                 "%s", parent_path);
                   1169:     } else if (pci_dev == NULL || pci_dev->name == NULL) {
                   1170:         snprintf(config.path, sizeof(config.path),
                   1171:                 "%s/pci%x,%x", parent_path, vid, did);
                   1172:     }
                   1173:     else {
                   1174:         snprintf(config.path, sizeof(config.path),
                   1175:                 "%s/%s", parent_path, pci_dev->name);
                   1176:     }
                   1177: 
                   1178:     PCI_DPRINTF("%s - ", config.path);
                   1179: 
                   1180:     config.dev = addr & 0x00FFFFFF;
                   1181: 
                   1182:     switch (class) {
                   1183:     case PCI_BASE_CLASS_BRIDGE:
                   1184:         if (subclass != PCI_SUBCLASS_BRIDGE_HOST) {
                   1185:             REGISTER_NAMED_NODE_PHANDLE(ob_pci_bus_node, config.path, phandle);
                   1186:         }
                   1187:         break;
                   1188:     default:
                   1189:         REGISTER_NAMED_NODE_PHANDLE(ob_pci_simple_node, config.path, phandle);
                   1190:         break;
                   1191:     }
                   1192: 
                   1193:     if (is_host_bridge) {
                   1194:         phandle = find_dev(config.path);
                   1195: 
                   1196:         if (get_property(phandle, "vendor-id", NULL)) {
                   1197:             PCI_DPRINTF("host bridge already configured\n");
                   1198:             return;
                   1199:         }
                   1200:     }
                   1201: 
                   1202:     activate_dev(phandle);
                   1203: 
                   1204:     if (htype & PCI_HEADER_TYPE_BRIDGE) {
                   1205:         num_bars = 2;
                   1206:         rom_bar  = PCI_ROM_ADDRESS1;
                   1207:     } else {
                   1208:         num_bars = 6;
                   1209:         rom_bar  = PCI_ROM_ADDRESS;
                   1210:     }
                   1211: 
                   1212:     ob_pci_configure(addr, &config, num_bars, rom_bar,
                   1213:                      mem_base, io_base);
                   1214: 
                   1215:     ob_pci_add_properties(phandle, addr, pci_dev, &config, num_bars);
                   1216: 
                   1217:     if (!is_host_bridge) {
                   1218:         pci_set_reg(phandle, &config, num_bars);
                   1219:     }
                   1220: 
                   1221:     /* call device-specific configuration callback */
                   1222:     if (pci_dev && pci_dev->config_cb) {
                   1223:         //activate_device(config.path);
                   1224:         pci_dev->config_cb(&config);
                   1225:     }
                   1226: 
                   1227:     /* device is configured so we may move it out of scope */
                   1228:     device_end();
                   1229: 
                   1230:     /* scan bus behind bridge device */
                   1231:     //if (htype & PCI_HEADER_TYPE_BRIDGE && class == PCI_BASE_CLASS_BRIDGE) {
                   1232:     if ( class == PCI_BASE_CLASS_BRIDGE &&
                   1233:             ( subclass == PCI_SUBCLASS_BRIDGE_PCI ||
                   1234:               subclass == PCI_SUBCLASS_BRIDGE_HOST ) ) {
                   1235: 
                   1236:         if (subclass == PCI_SUBCLASS_BRIDGE_PCI) {
                   1237:             /* reserve next pci bus number for this PCI bridge */
                   1238:             ++(*bus_num);
                   1239:         }
                   1240: 
                   1241:         ob_configure_pci_bridge(addr, bus_num, mem_base, io_base, bus, &config);
                   1242:     }
                   1243: }
                   1244: 
                   1245: int ob_pci_init(void)
                   1246: {
                   1247:     int bus, devnum, fn;
                   1248:     uint8_t class, subclass;
                   1249:     unsigned long mem_base, io_base;
                   1250: 
                   1251:     pci_config_t config = {}; /* host bridge */
                   1252:     phandle_t phandle_host;
                   1253: 
                   1254:     PCI_DPRINTF("Initializing PCI host bridge...\n");
                   1255: 
                   1256:     activate_device("/");
                   1257: 
                   1258:     /* Find all PCI bridges */
                   1259: 
                   1260:     mem_base = arch->pci_mem_base;
                   1261:     /* I/O ports under 0x400 are used by devices mapped at fixed
                   1262:        location. */
                   1263:     io_base = arch->io_base + 0x400;
                   1264: 
                   1265:     bus = 0;
                   1266: 
                   1267:     for (devnum = 0; devnum < 32; devnum++) {
                   1268:         /* scan only fn 0 */
                   1269:         fn = 0;
                   1270: 
                   1271:         if (!ob_pci_read_identification(bus, devnum, fn,
                   1272:                                         0, 0, &class, &subclass)) {
                   1273:             continue;
                   1274:         }
                   1275: 
                   1276:         if (class != PCI_BASE_CLASS_BRIDGE || subclass != PCI_SUBCLASS_BRIDGE_HOST) {
                   1277:             continue;
                   1278:         }
                   1279: 
                   1280:         /* create root node for host PCI bridge */
                   1281: 
                   1282:         /* configure  */
                   1283:         snprintf(config.path, sizeof(config.path), "/pci");
                   1284: 
                   1285:         REGISTER_NAMED_NODE_PHANDLE(ob_pci_bus_node, config.path, phandle_host);
                   1286: 
                   1287:         pci_host_set_reg(phandle_host);
                   1288: 
                   1289:         /* update device path after changing "reg" property */
                   1290:         ob_pci_reload_device_path(phandle_host, &config);
                   1291: 
                   1292:         ob_configure_pci_device(config.path, &bus, &mem_base, &io_base,
                   1293:                 bus, devnum, fn, 0);
                   1294: 
                   1295:         /* we expect single host PCI bridge
                   1296:            but this may be machine-specific */
                   1297:         break;
                   1298:     }
                   1299: 
                   1300: 
                   1301:     device_end();
                   1302: 
                   1303:     return 0;
                   1304: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.