summaryrefslogtreecommitdiffstats
path: root/qemu/roms/openbios/drivers/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/openbios/drivers/pci.c')
-rw-r--r--qemu/roms/openbios/drivers/pci.c1600
1 files changed, 0 insertions, 1600 deletions
diff --git a/qemu/roms/openbios/drivers/pci.c b/qemu/roms/openbios/drivers/pci.c
deleted file mode 100644
index 5062f302f..000000000
--- a/qemu/roms/openbios/drivers/pci.c
+++ /dev/null
@@ -1,1600 +0,0 @@
-/*
- * OpenBIOS pci driver
- *
- * This driver is compliant to the
- * PCI bus binding to IEEE 1275-1994 Rev 2.1
- *
- * (C) 2004 Stefan Reinauer <stepan@openbios.org>
- * (C) 2005 Ed Schouten <ed@fxq.nl>
- *
- * Some parts from OpenHackWare-0.4, Copyright (c) 2004-2005 Jocelyn Mayer
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2
- *
- */
-
-#include "config.h"
-#include "libopenbios/bindings.h"
-#include "libopenbios/ofmem.h"
-#include "kernel/kernel.h"
-#include "drivers/pci.h"
-#include "libc/byteorder.h"
-#include "libc/vsprintf.h"
-
-#include "drivers/drivers.h"
-#include "drivers/vga.h"
-#include "packages/video.h"
-#include "libopenbios/video.h"
-#include "timer.h"
-#include "pci.h"
-#include "pci_database.h"
-#ifdef CONFIG_DRIVER_MACIO
-#include "cuda.h"
-#include "macio.h"
-#endif
-#ifdef CONFIG_DRIVER_USB
-#include "drivers/usb.h"
-#endif
-
-#if defined (CONFIG_DEBUG_PCI)
-# define PCI_DPRINTF(format, ...) printk(format, ## __VA_ARGS__)
-#else
-# define PCI_DPRINTF(format, ...) do { } while (0)
-#endif
-
-#define set_bool_property(ph, name) set_property(ph, name, NULL, 0);
-
-/* DECLARE data structures for the nodes. */
-
-DECLARE_UNNAMED_NODE( ob_pci_bus_node, INSTALL_OPEN, 2*sizeof(int) );
-DECLARE_UNNAMED_NODE( ob_pci_simple_node, INSTALL_OPEN, 2*sizeof(int) );
-DECLARE_UNNAMED_NODE( ob_pci_empty_node, 0, 2*sizeof(int) );
-
-const pci_arch_t *arch;
-
-#define IS_NOT_RELOCATABLE 0x80000000
-#define IS_PREFETCHABLE 0x40000000
-#define IS_ALIASED 0x20000000
-
-enum {
- CONFIGURATION_SPACE = 0,
- IO_SPACE = 1,
- MEMORY_SPACE_32 = 2,
- MEMORY_SPACE_64 = 3,
-};
-
-static int encode_int32_cells(int num_cells, u32 *prop, ucell val)
-{
- int i = 0;
-
- /* hi ... lo */
- for (i=0; i < num_cells; ++i) {
- prop[num_cells - i - 1] = val;
- val >>= 16;
- val >>= 16;
- }
-
- return num_cells;
-}
-
-static inline int pci_encode_phys_addr(u32 *phys, int flags, int space_code,
- pci_addr dev, uint8_t reg, uint64_t addr)
-{
-
- /* phys.hi */
-
- phys[0] = flags | (space_code << 24) | dev | reg;
-
- /* phys.mid */
-
- phys[1] = addr >> 32;
-
- /* phys.lo */
-
- phys[2] = addr;
-
- return 3;
-}
-
-static inline int pci_encode_size(u32 *prop, uint64_t size)
-{
- return encode_int32_cells(2, prop, size);
-}
-
-static int host_address_cells(void)
-{
- return get_int_property(find_dev("/"), "#address-cells", NULL);
-}
-
-static int host_encode_phys_addr(u32 *prop, ucell addr)
-{
- return encode_int32_cells(host_address_cells(), prop, addr);
-}
-
-static int host_size_cells(void)
-{
- return get_int_property(find_dev("/"), "#size-cells", NULL);
-}
-
-/*
-static int parent_address_cells(void)
-{
- phandle_t parent_ph = ih_to_phandle(my_parent());
- return get_int_property(parent_ph, "#address-cells", NULL);
-}
-
-static int parent_size_cells(void)
-{
- phandle_t parent_ph = ih_to_phandle(my_parent());
- return get_int_property(parent_ph, "#size-cells", NULL);
-}
-*/
-
-#if defined(CONFIG_DEBUG_PCI)
-static void dump_reg_property(const char* description, int nreg, u32 *reg)
-{
- int i;
- printk("%s reg", description);
- for (i=0; i < nreg; ++i) {
- printk(" %08X", reg[i]);
- }
- printk("\n");
-}
-#endif
-
-static unsigned long pci_bus_addr_to_host_addr(int space, uint32_t ba)
-{
- if (space == IO_SPACE) {
- return arch->io_base + (unsigned long)ba;
- } else if (space == MEMORY_SPACE_32) {
- return arch->host_pci_base + (unsigned long)ba;
- } else {
- /* Return unaltered to aid debugging property values */
- return (unsigned long)ba;
- }
-}
-
-static void
-ob_pci_open(int *idx)
-{
- int ret=1;
- RET ( -ret );
-}
-
-static void
-ob_pci_close(int *idx)
-{
-}
-
-static void
-ob_pci_initialize(int *idx)
-{
-}
-
-/* ( str len -- phys.lo phys.mid phys.hi ) */
-
-static void
-ob_pci_decode_unit(int *idx)
-{
- ucell hi, mid, lo;
- const char *arg = pop_fstr_copy();
- int dev, fn, reg, ss, n, p, t;
- int bus = 0; /* no information */
- char *ptr;
-
- PCI_DPRINTF("ob_pci_decode_unit idx=%p\n", idx);
-
- fn = 0;
- reg = 0;
- n = 0;
- p = 0;
- t = 0;
-
- ptr = (char*)arg;
- if (*ptr == 'n') {
- n = IS_NOT_RELOCATABLE;
- ptr++;
- }
- if (*ptr == 'i') {
- ss = IO_SPACE;
- ptr++;
- if (*ptr == 't') {
- t = IS_ALIASED;
- ptr++;
- }
-
- /* DD,F,RR,NNNNNNNN */
-
- dev = strtol(ptr, &ptr, 16);
- ptr++;
- fn = strtol(ptr, &ptr, 16);
- ptr++;
- reg = strtol(ptr, &ptr, 16);
- ptr++;
- lo = strtol(ptr, &ptr, 16);
- mid = 0;
-
- } else if (*ptr == 'm') {
- ss = MEMORY_SPACE_32;
- ptr++;
- if (*ptr == 't') {
- t = IS_ALIASED;
- ptr++;
- }
- if (*ptr == 'p') {
- p = IS_PREFETCHABLE;
- ptr++;
- }
-
- /* DD,F,RR,NNNNNNNN */
-
- dev = strtol(ptr, &ptr, 16);
- ptr++;
- fn = strtol(ptr, &ptr, 16);
- ptr++;
- reg = strtol(ptr, &ptr, 16);
- ptr++;
- lo = strtol(ptr, &ptr, 16);
- mid = 0;
-
- } else if (*ptr == 'x') {
- unsigned long long addr64;
- ss = MEMORY_SPACE_64;
- ptr++;
- if (*ptr == 'p') {
- p = IS_PREFETCHABLE;
- ptr++;
- }
-
- /* DD,F,RR,NNNNNNNNNNNNNNNN */
-
- dev = strtol(ptr, &ptr, 16);
- ptr++;
- fn = strtol(ptr, &ptr, 16);
- ptr++;
- reg = strtol(ptr, &ptr, 16);
- ptr++;
- addr64 = strtoll(ptr, &ptr, 16);
- lo = (ucell)addr64;
- mid = addr64 >> 32;
-
- } else {
- ss = CONFIGURATION_SPACE;
- /* "DD" or "DD,FF" */
- dev = strtol(ptr, &ptr, 16);
- if (*ptr == ',') {
- ptr++;
- fn = strtol(ptr, NULL, 16);
- }
- lo = 0;
- mid = 0;
- }
- free((char*)arg);
-
- hi = n | p | t | (ss << 24) | (bus << 16) | (dev << 11) | (fn << 8) | reg;
-
- PUSH(lo);
- PUSH(mid);
- PUSH(hi);
-
- PCI_DPRINTF("ob_pci_decode_unit idx=%p addr="
- FMT_ucellx " " FMT_ucellx " " FMT_ucellx "\n",
- idx, lo, mid, hi);
-}
-
-/* ( phys.lo phy.mid phys.hi -- str len ) */
-
-static void
-ob_pci_encode_unit(int *idx)
-{
- char buf[28];
- cell hi = POP();
- cell mid = POP();
- cell lo = POP();
- int n, p, t, ss, dev, fn, reg;
-
- n = hi & IS_NOT_RELOCATABLE;
- p = hi & IS_PREFETCHABLE;
- t = hi & IS_ALIASED;
- ss = (hi >> 24) & 0x03;
-
- dev = (hi >> 11) & 0x1F;
- fn = (hi >> 8) & 0x07;
- reg = hi & 0xFF;
-
- switch(ss) {
- case CONFIGURATION_SPACE:
-
- if (fn == 0) /* DD */
- snprintf(buf, sizeof(buf), "%x", dev);
- else /* DD,F */
- snprintf(buf, sizeof(buf), "%x,%x", dev, fn);
- break;
-
- case IO_SPACE:
-
- /* [n]i[t]DD,F,RR,NNNNNNNN */
- snprintf(buf, sizeof(buf), "%si%s%x,%x,%x," FMT_ucellx,
- n ? "n" : "", /* relocatable */
- t ? "t" : "", /* aliased */
- dev, fn, reg, t ? lo & 0x03FF : lo);
- break;
-
- case MEMORY_SPACE_32:
-
- /* [n]m[t][p]DD,F,RR,NNNNNNNN */
- snprintf(buf, sizeof(buf), "%sm%s%s%x,%x,%x," FMT_ucellx,
- n ? "n" : "", /* relocatable */
- t ? "t" : "", /* aliased */
- p ? "p" : "", /* prefetchable */
- dev, fn, reg, lo );
- break;
-
- case MEMORY_SPACE_64:
-
- /* [n]x[p]DD,F,RR,NNNNNNNNNNNNNNNN */
- snprintf(buf, sizeof(buf), "%sx%s%x,%x,%x,%llx",
- n ? "n" : "", /* relocatable */
- p ? "p" : "", /* prefetchable */
- dev, fn, reg, ((long long)mid << 32) | (long long)lo);
- break;
- }
- push_str(buf);
-
- PCI_DPRINTF("ob_pci_encode_unit space=%d dev=%d fn=%d buf=%s\n",
- ss, dev, fn, buf);
-}
-
-/* ( pci-addr.lo pci-addr.mid pci-addr.hi size -- virt ) */
-
-static void
-ob_pci_map_in(int *idx)
-{
- phys_addr_t phys;
- uint32_t ba;
- ucell size, virt, tmp;
- int space;
-
- PCI_DPRINTF("ob_pci_bar_map_in idx=%p\n", idx);
-
- size = POP();
- tmp = POP();
- POP();
- ba = POP();
-
- /* Get the space from the pci-addr.hi */
- space = ((tmp & PCI_RANGE_TYPE_MASK) >> 24);
-
- phys = pci_bus_addr_to_host_addr(space, ba);
-
-#if defined(CONFIG_OFMEM)
- ofmem_claim_phys(phys, size, 0);
-
-#if defined(CONFIG_PPC)
- /* For some reason PPC gets upset when virt != phys for map-in... */
- virt = ofmem_claim_virt(phys, size, 0);
-#else
- virt = ofmem_claim_virt(-1, size, size);
-#endif
-
- ofmem_map(phys, virt, size, ofmem_arch_io_translation_mode(phys));
-
-#else
- virt = size; /* Keep compiler quiet */
- virt = phys;
-#endif
-
- PUSH(virt);
-}
-
-NODE_METHODS(ob_pci_bus_node) = {
- { NULL, ob_pci_initialize },
- { "open", ob_pci_open },
- { "close", ob_pci_close },
- { "decode-unit", ob_pci_decode_unit },
- { "encode-unit", ob_pci_encode_unit },
- { "pci-map-in", ob_pci_map_in },
-};
-
-NODE_METHODS(ob_pci_simple_node) = {
- { NULL, ob_pci_initialize },
- { "open", ob_pci_open },
- { "close", ob_pci_close },
-};
-
-NODE_METHODS(ob_pci_empty_node) = {
- { NULL, ob_pci_initialize }
-};
-
-static void pci_set_bus_range(const pci_config_t *config)
-{
- phandle_t dev = find_dev(config->path);
- u32 props[2];
-
- props[0] = config->secondary_bus;
- props[1] = config->subordinate_bus;
-
- PCI_DPRINTF("setting bus range for %s PCI device, "
- "package handle " FMT_ucellx " "
- "bus primary=%d secondary=%d subordinate=%d\n",
- config->path,
- dev,
- config->primary_bus,
- config->secondary_bus,
- config->subordinate_bus);
-
-
- set_property(dev, "bus-range", (char *)props, 2 * sizeof(props[0]));
-}
-
-static void pci_host_set_reg(phandle_t phandle)
-{
- phandle_t dev = phandle;
-
- /* at most 2 integers for address and size */
- u32 props[4];
- int ncells = 0;
-
- ncells += encode_int32_cells(host_address_cells(), props + ncells,
- arch->cfg_base);
-
- ncells += encode_int32_cells(host_size_cells(), props + ncells,
- arch->cfg_len);
-
- set_property(dev, "reg", (char *)props, ncells * sizeof(props[0]));
-
-#if defined(CONFIG_DEBUG_PCI)
- dump_reg_property("pci_host_set_reg", 4, props);
-#endif
-}
-
-/* child-phys : parent-phys : size */
-/* 3 cells for PCI : 2 cells for 64bit parent : 2 cells for PCI */
-
-static void pci_host_set_ranges(const pci_config_t *config)
-{
- phandle_t dev = get_cur_dev();
- u32 props[32];
- int ncells;
-
- ncells = 0;
-
-#ifdef CONFIG_SPARC64
- /* While configuration space isn't mentioned in the IEEE-1275 PCI
- bindings, it appears in the PCI host bridge ranges property in
- real device trees. Hence we disable this range for all host
- bridges except for SPARC, particularly as it causes Darwin/OS X
- to incorrectly calculated PCI memory space ranges on PPC. */
- ncells += pci_encode_phys_addr(props + ncells, 0, CONFIGURATION_SPACE,
- config->dev, 0, 0);
- ncells += host_encode_phys_addr(props + ncells, arch->cfg_addr);
- ncells += pci_encode_size(props + ncells, arch->cfg_len);
-#endif
-
- if (arch->io_base) {
- ncells += pci_encode_phys_addr(props + ncells, 0, IO_SPACE,
- config->dev, 0, 0);
- ncells += host_encode_phys_addr(props + ncells, arch->io_base);
- ncells += pci_encode_size(props + ncells, arch->io_len);
- }
- if (arch->rbase) {
- ncells += pci_encode_phys_addr(props + ncells, 0, MEMORY_SPACE_32,
- config->dev, 0, 0);
- ncells += host_encode_phys_addr(props + ncells, arch->rbase);
- ncells += pci_encode_size(props + ncells, arch->rlen);
- }
- if (arch->pci_mem_base) {
- ncells += pci_encode_phys_addr(props + ncells, 0, MEMORY_SPACE_32,
- config->dev, 0, arch->pci_mem_base);
- ncells += host_encode_phys_addr(props + ncells, arch->host_pci_base +
- arch->pci_mem_base);
- ncells += pci_encode_size(props + ncells, arch->mem_len);
- }
- set_property(dev, "ranges", (char *)props, ncells * sizeof(props[0]));
-}
-
-int host_config_cb(const pci_config_t *config)
-{
- //XXX this overrides "reg" property
- pci_host_set_reg(get_cur_dev());
- pci_host_set_ranges(config);
-
- return 0;
-}
-
-static int sabre_configure(phandle_t dev)
-{
- uint32_t props[28];
-
- props[0] = 0xc0000000;
- props[1] = 0x20000000;
- set_property(dev, "virtual-dma", (char *)props, 2 * sizeof(props[0]));
- props[0] = 1;
- set_property(dev, "#virtual-dma-size-cells", (char *)props,
- sizeof(props[0]));
- set_property(dev, "#virtual-dma-addr-cells", (char *)props,
- sizeof(props[0]));
-
- set_property(dev, "no-streaming-cache", (char *)props, 0);
-
- props[0] = 0x000007f0;
- props[1] = 0x000007ee;
- props[2] = 0x000007ef;
- props[3] = 0x000007e5;
- set_property(dev, "interrupts", (char *)props, 4 * sizeof(props[0]));
- props[0] = 0x0000001f;
- set_property(dev, "upa-portid", (char *)props, 1 * sizeof(props[0]));
- return 0;
-}
-
-int sabre_config_cb(const pci_config_t *config)
-{
- host_config_cb(config);
-
- return sabre_configure(get_cur_dev());
-}
-
-int bridge_config_cb(const pci_config_t *config)
-{
- phandle_t aliases;
-
- aliases = find_dev("/aliases");
- set_property(aliases, "bridge", config->path, strlen(config->path) + 1);
-
- return 0;
-}
-
-int ide_config_cb2 (const pci_config_t *config)
-{
- ob_ide_init(config->path,
- config->assigned[0] & ~0x0000000F,
- (config->assigned[1] & ~0x0000000F) + 2,
- config->assigned[2] & ~0x0000000F,
- (config->assigned[3] & ~0x0000000F) + 2);
- return 0;
-}
-
-int eth_config_cb (const pci_config_t *config)
-{
- phandle_t ph = get_cur_dev();
-
- set_property(ph, "network-type", "ethernet", 9);
- set_property(ph, "removable", "network", 8);
- set_property(ph, "category", "net", 4);
-
- return 0;
-}
-
-static inline void pci_decode_pci_addr(pci_addr addr, int *flags,
- int *space_code, uint32_t *mask)
-{
- *flags = 0;
-
- if (addr & 0x01) {
- *space_code = IO_SPACE;
- *mask = 0x00000001;
- } else {
- if (addr & 0x04) {
- *space_code = MEMORY_SPACE_64;
- *flags |= IS_NOT_RELOCATABLE; /* XXX: why not relocatable? */
- } else {
- *space_code = MEMORY_SPACE_32;
- }
-
- if (addr & 0x08) {
- *flags |= IS_PREFETCHABLE;
- }
-
- *mask = 0x0000000F;
- }
-}
-
-/*
- * "Designing PCI Cards and Drivers for Power Macintosh Computers", p. 454
- *
- * "AAPL,address" provides an array of 32-bit logical addresses
- * Nth entry corresponding to Nth "assigned-address" base address entry.
- */
-
-static void pci_set_AAPL_address(const pci_config_t *config)
-{
- phandle_t dev = get_cur_dev();
- cell props[7];
- uint32_t mask;
- int ncells, i, flags, space_code;
-
- ncells = 0;
- for (i = 0; i < 6; i++) {
- if (!config->assigned[i] || !config->sizes[i])
- continue;
- pci_decode_pci_addr(config->assigned[i],
- &flags, &space_code, &mask);
-
- props[ncells++] = pci_bus_addr_to_host_addr(space_code,
- config->assigned[i] & ~mask);
- }
- if (ncells)
- set_property(dev, "AAPL,address", (char *)props,
- ncells * sizeof(cell));
-}
-
-static void pci_set_assigned_addresses(phandle_t phandle,
- const pci_config_t *config, int num_bars)
-{
- phandle_t dev = phandle;
- u32 props[32];
- int ncells;
- int i;
- uint32_t mask;
- int flags, space_code;
-
- ncells = 0;
- for (i = 0; i < num_bars; i++) {
- /* consider only bars with non-zero region size */
- if (!config->sizes[i])
- continue;
- pci_decode_pci_addr(config->assigned[i],
- &flags, &space_code, &mask);
-
- ncells += pci_encode_phys_addr(props + ncells,
- flags, space_code, config->dev,
- PCI_BASE_ADDR_0 + (i * sizeof(uint32_t)),
- config->assigned[i] & ~mask);
-
- props[ncells++] = 0x00000000;
- props[ncells++] = config->sizes[i];
- }
- if (ncells)
- set_property(dev, "assigned-addresses", (char *)props,
- ncells * sizeof(props[0]));
-}
-
-/* call after writing "reg" property to update config->path */
-static void ob_pci_reload_device_path(phandle_t phandle, pci_config_t *config)
-{
- /* since "name" and "reg" are now assigned
- we need to reload current node name */
-
- PUSH(phandle);
- fword("get-package-path");
- char *new_path = pop_fstr_copy();
- if (new_path) {
- if (0 != strcmp(config->path, new_path)) {
- PCI_DPRINTF("\n=== CHANGED === package path old=%s new=%s\n",
- config->path, new_path);
- strncpy(config->path, new_path, sizeof(config->path));
- config->path[sizeof(config->path)-1] = '\0';
- }
- free(new_path);
- } else {
- PCI_DPRINTF("\n=== package path old=%s new=NULL\n", config->path);
- }
-}
-
-static void pci_set_reg(phandle_t phandle,
- pci_config_t *config, int num_bars)
-{
- phandle_t dev = phandle;
- u32 props[38];
- int ncells;
- int i;
- uint32_t mask;
- int space_code, flags;
-
- ncells = 0;
-
- /* first (addr, size) pair is the beginning of configuration address space */
- ncells += pci_encode_phys_addr(props + ncells, 0, CONFIGURATION_SPACE,
- config->dev, 0, 0);
-
- ncells += pci_encode_size(props + ncells, 0);
-
- for (i = 0; i < num_bars; i++) {
- /* consider only bars with non-zero region size */
- if (!config->sizes[i])
- continue;
-
- pci_decode_pci_addr(config->regions[i],
- &flags, &space_code, &mask);
-
- ncells += pci_encode_phys_addr(props + ncells,
- flags, space_code, config->dev,
- PCI_BASE_ADDR_0 + (i * sizeof(uint32_t)),
- config->regions[i] & ~mask);
-
- /* set size */
- ncells += pci_encode_size(props + ncells, config->sizes[i]);
- }
-
- set_property(dev, "reg", (char *)props, ncells * sizeof(props[0]));
- ob_pci_reload_device_path(dev, config);
-
-#if defined(CONFIG_DEBUG_PCI)
- dump_reg_property("pci_set_reg", ncells, props);
-#endif
-}
-
-
-static void pci_set_ranges(const pci_config_t *config)
-{
- phandle_t dev = get_cur_dev();
- u32 props[32];
- int ncells;
- int i;
- uint32_t mask;
- int flags;
- int space_code;
-
- ncells = 0;
- for (i = 0; i < 6; i++) {
- if (!config->assigned[i] || !config->sizes[i])
- continue;
-
- /* child address */
-
- props[ncells++] = 0x00000000;
-
- /* parent address */
-
- pci_decode_pci_addr(config->assigned[i],
- &flags, &space_code, &mask);
- ncells += pci_encode_phys_addr(props + ncells, flags, space_code,
- config->dev, 0x10 + i * 4,
- config->assigned[i] & ~mask);
-
- /* size */
-
- props[ncells++] = config->sizes[i];
- }
- set_property(dev, "ranges", (char *)props, ncells * sizeof(props[0]));
-}
-
-int macio_heathrow_config_cb (const pci_config_t *config)
-{
- pci_set_ranges(config);
-
-#ifdef CONFIG_DRIVER_MACIO
- ob_macio_heathrow_init(config->path, config->assigned[0] & ~0x0000000F);
-#endif
- return 0;
-}
-
-int macio_keylargo_config_cb (const pci_config_t *config)
-{
- pci_set_ranges(config);
-
-#ifdef CONFIG_DRIVER_MACIO
- ob_macio_keylargo_init(config->path, config->assigned[0] & ~0x0000000F);
-#endif
- return 0;
-}
-
-int vga_config_cb (const pci_config_t *config)
-{
- unsigned long rom;
- uint32_t rom_size, size, mask;
- int flags, space_code;
- phandle_t ph;
-
- if (config->assigned[0] != 0x00000000) {
- setup_video();
-
- pci_decode_pci_addr(config->assigned[1],
- &flags, &space_code, &mask);
-
- rom = pci_bus_addr_to_host_addr(space_code,
- config->assigned[1] & ~0x0000000F);
-
- rom_size = config->sizes[1];
-
- ph = get_cur_dev();
-
- if (rom_size >= 8) {
- const char *p;
-
- p = (const char *)rom;
- if (p[0] == 'N' && p[1] == 'D' && p[2] == 'R' && p[3] == 'V') {
- size = *(uint32_t*)(p + 4);
- set_property(ph, "driver,AAPL,MacOS,PowerPC", p + 8, size);
- }
- }
-
- /* Currently we don't read FCode from the hardware but execute it directly */
- feval("['] vga-driver-fcode 2 cells + 1 byte-load");
-
-#ifdef CONFIG_MOL
- /* Install special words for Mac On Linux */
- molvideo_init();
-#endif
-
- }
-
- return 0;
-}
-
-int ebus_config_cb(const pci_config_t *config)
-{
-#ifdef CONFIG_DRIVER_EBUS
- phandle_t dev = get_cur_dev();
- uint32_t props[12];
- int ncells;
- int i;
- uint32_t mask;
- int flags, space_code;
-
- props[0] = 0x14;
- props[1] = 0x3f8;
- props[2] = 1;
- props[3] = find_dev("/");
- props[4] = 0x2b;
- set_property(dev, "interrupt-map", (char *)props, 5 * sizeof(props[0]));
-
- props[0] = 0x000001ff;
- props[1] = 0xffffffff;
- props[2] = 3;
- set_property(dev, "interrupt-map-mask", (char *)props, 3 * sizeof(props[0]));
-
- /* Build ranges property from the BARs */
- ncells = 0;
- for (i = 0; i < 6; i++) {
- /* consider only bars with non-zero region size */
- if (!config->sizes[i])
- continue;
-
- pci_decode_pci_addr(config->assigned[i],
- &flags, &space_code, &mask);
-
- props[ncells++] = PCI_BASE_ADDR_0 + (i * sizeof(uint32_t));
- props[ncells++] = 0x0;
-
- ncells += pci_encode_phys_addr(props + ncells,
- flags, space_code, config->dev,
- PCI_BASE_ADDR_0 + (i * sizeof(uint32_t)),
- config->assigned[i] & ~mask);
-
- props[ncells++] = config->sizes[i];
- }
-
- set_property(dev, "ranges", (char *)props, ncells * sizeof(props[0]));
-
- /* Build eeprom node */
- fword("new-device");
- PUSH(0x14);
- fword("encode-int");
- PUSH(0x2000);
- fword("encode-int");
- fword("encode+");
- PUSH(0x2000);
- fword("encode-int");
- fword("encode+");
- push_str("reg");
- fword("property");
-
- push_str("mk48t59");
- fword("model");
-
- push_str("eeprom");
- fword("device-name");
- fword("finish-device");
-
-#ifdef CONFIG_DRIVER_FLOPPY
- ob_floppy_init(config->path, "fdthree", 0x3f0ULL, 0);
-#endif
-#ifdef CONFIG_DRIVER_PC_SERIAL
- ob_pc_serial_init(config->path, "su", (PCI_BASE_ADDR_1 | 0ULL) << 32, 0x3f8ULL, 0);
-#endif
-#ifdef CONFIG_DRIVER_PC_KBD
- ob_pc_kbd_init(config->path, "kb_ps2", (PCI_BASE_ADDR_1 | 0ULL) << 32, 0x60ULL, 0);
-#endif
-#endif
- return 0;
-}
-
-int i82378_config_cb(const pci_config_t *config)
-{
-#ifdef CONFIG_DRIVER_PC_SERIAL
- ob_pc_serial_init(config->path, "serial", arch->io_base, 0x3f8ULL, 0);
-#endif
-#ifdef CONFIG_DRIVER_PC_KBD
- ob_pc_kbd_init(config->path, "8042", arch->io_base, 0x60ULL, 0);
-#endif
-#ifdef CONFIG_DRIVER_IDE
- ob_ide_init(config->path, 0x1f0, 0x3f6, 0x170, 0x376);
-#endif
-
- return 0;
-}
-
-int usb_ohci_config_cb(const pci_config_t *config)
-{
-#ifdef CONFIG_DRIVER_USB
- ob_usb_ohci_init(config->path, 0x80000000 | config->dev);
-#endif
- return 0;
-}
-
-static void ob_pci_add_properties(phandle_t phandle,
- pci_addr addr, const pci_dev_t *pci_dev,
- const pci_config_t *config, int num_bars)
-{
- /* cannot use get_cur_dev() path resolution since "name" and "reg"
- properties are being changed */
- phandle_t dev=phandle;
- int status,id;
- uint16_t vendor_id, device_id;
- uint8_t rev;
- uint8_t class_prog;
- uint32_t class_code;
-
- vendor_id = pci_config_read16(addr, PCI_VENDOR_ID);
- device_id = pci_config_read16(addr, PCI_DEVICE_ID);
- rev = pci_config_read8(addr, PCI_REVISION_ID);
- class_prog = pci_config_read8(addr, PCI_CLASS_PROG);
- class_code = pci_config_read16(addr, PCI_CLASS_DEVICE);
-
- if (pci_dev) {
- /**/
- if (pci_dev->name) {
- push_str(pci_dev->name);
- fword("encode-string");
- push_str("name");
- fword("property");
- } else {
- char path[256];
- snprintf(path, sizeof(path),
- "pci%x,%x", vendor_id, device_id);
- push_str(path);
- fword("encode-string");
- push_str("name");
- fword("property");
- }
- } else {
- PCI_DPRINTF("*** missing pci_dev\n");
- }
-
- /* create properties as described in 2.5 */
-
- set_int_property(dev, "vendor-id", vendor_id);
- set_int_property(dev, "device-id", device_id);
- set_int_property(dev, "revision-id", rev);
- set_int_property(dev, "class-code", class_code << 8 | class_prog);
-
- if (config->irq_pin) {
- OLDWORLD(set_int_property(dev, "AAPL,interrupts",
- config->irq_line));
-#if defined(CONFIG_SPARC64)
- set_int_property(dev, "interrupts", config->irq_pin);
-#else
- NEWWORLD(set_int_property(dev, "interrupts", config->irq_pin));
-#endif
- }
-
- set_int_property(dev, "min-grant", pci_config_read8(addr, PCI_MIN_GNT));
- set_int_property(dev, "max-latency", pci_config_read8(addr, PCI_MAX_LAT));
-
- status=pci_config_read16(addr, PCI_STATUS);
-
- set_int_property(dev, "devsel-speed",
- (status&PCI_STATUS_DEVSEL_MASK)>>10);
-
- if(status&PCI_STATUS_FAST_BACK)
- set_bool_property(dev, "fast-back-to-back");
- if(status&PCI_STATUS_66MHZ)
- set_bool_property(dev, "66mhz-capable");
- if(status&PCI_STATUS_UDF)
- set_bool_property(dev, "udf-supported");
-
- id=pci_config_read16(addr, PCI_SUBSYSTEM_VENDOR_ID);
- if(id)
- set_int_property(dev, "subsystem-vendor-id", id);
- id=pci_config_read16(addr, PCI_SUBSYSTEM_ID);
- if(id)
- set_int_property(dev, "subsystem-id", id);
-
- set_int_property(dev, "cache-line-size",
- pci_config_read16(addr, PCI_CACHE_LINE_SIZE));
-
- if (pci_dev) {
- if (pci_dev->type) {
- push_str(pci_dev->type);
- fword("encode-string");
- push_str("device_type");
- fword("property");
- }
- if (pci_dev->model) {
- push_str(pci_dev->model);
- fword("encode-string");
- push_str("model");
- fword("property");
- }
- if (pci_dev->compat)
- set_property(dev, "compatible",
- pci_dev->compat, pci_compat_len(pci_dev));
-
- if (pci_dev->acells)
- set_int_property(dev, "#address-cells",
- pci_dev->acells);
- if (pci_dev->scells)
- set_int_property(dev, "#size-cells",
- pci_dev->scells);
- if (pci_dev->icells)
- set_int_property(dev, "#interrupt-cells",
- pci_dev->icells);
- }
-
- pci_set_assigned_addresses(phandle, config, num_bars);
-
- if (is_apple()) {
- pci_set_AAPL_address(config);
- }
-
- PCI_DPRINTF("\n");
-}
-
-#ifdef CONFIG_XBOX
-static char pci_xbox_blacklisted (int bus, int devnum, int fn)
-{
- /*
- * The Xbox MCPX chipset is a derivative of the nForce 1
- * chipset. It almost has the same bus layout; some devices
- * cannot be used, because they have been removed.
- */
-
- /*
- * Devices 00:00.1 and 00:00.2 used to be memory controllers on
- * the nForce chipset, but on the Xbox, using them will lockup
- * the chipset.
- */
- if ((bus == 0) && (devnum == 0) && ((fn == 1) || (fn == 2)))
- return 1;
-
- /*
- * Bus 1 only contains a VGA controller at 01:00.0. When you try
- * to probe beyond that device, you only get garbage, which
- * could cause lockups.
- */
- if ((bus == 1) && ((devnum != 0) || (fn != 0)))
- return 1;
-
- /*
- * Bus 2 used to contain the AGP controller, but the Xbox MCPX
- * doesn't have one. Probing it can cause lockups.
- */
- if (bus >= 2)
- return 1;
-
- /*
- * The device is not blacklisted.
- */
- return 0;
-}
-#endif
-
-static void ob_pci_configure_bar(pci_addr addr, pci_config_t *config,
- int reg, int config_addr,
- uint32_t *p_omask,
- unsigned long *mem_base,
- unsigned long *io_base)
-{
- uint32_t smask, amask, size, reloc, min_align;
- unsigned long base;
-
- config->assigned[reg] = 0x00000000;
- config->sizes[reg] = 0x00000000;
-
- if ((*p_omask & 0x0000000f) == 0x4) {
- /* 64 bits memory mapping */
- PCI_DPRINTF("Skipping 64 bit BARs for %s\n", config->path);
- return;
- }
-
- config->regions[reg] = pci_config_read32(addr, config_addr);
-
- /* get region size */
-
- pci_config_write32(addr, config_addr, 0xffffffff);
- smask = pci_config_read32(addr, config_addr);
- if (smask == 0x00000000 || smask == 0xffffffff)
- return;
-
- if (smask & 0x00000001 && reg != 6) {
- /* I/O space */
- base = *io_base;
- min_align = 1 << 7;
- amask = 0x00000001;
- } else {
- /* Memory Space */
- base = *mem_base;
- min_align = 1 << 16;
- amask = 0x0000000F;
- if (reg == 6) {
- smask |= 1; /* ROM */
- }
- }
- *p_omask = smask & amask;
- smask &= ~amask;
- size = (~smask) + 1;
- config->sizes[reg] = size;
- reloc = base;
- if (size < min_align)
- size = min_align;
- reloc = (reloc + size -1) & ~(size - 1);
- if (*io_base == base) {
- PCI_DPRINTF("changing io_base from 0x%lx to 0x%x\n",
- *io_base, reloc + size);
- *io_base = reloc + size;
- } else {
- PCI_DPRINTF("changing mem_base from 0x%lx to 0x%x\n",
- *mem_base, reloc + size);
- *mem_base = reloc + size;
- }
- PCI_DPRINTF("Configuring BARs for %s: reloc 0x%x omask 0x%x "
- "io_base 0x%lx mem_base 0x%lx size 0x%x\n",
- config->path, reloc, *p_omask, *io_base, *mem_base, size);
- pci_config_write32(addr, config_addr, reloc | *p_omask);
- config->assigned[reg] = reloc | *p_omask;
-}
-
-static void ob_pci_configure_irq(pci_addr addr, pci_config_t *config)
-{
- uint8_t irq_pin, irq_line;
-
- irq_pin = pci_config_read8(addr, PCI_INTERRUPT_PIN);
- if (irq_pin) {
- config->irq_pin = irq_pin;
- irq_pin = (((config->dev >> 11) & 0x1F) + irq_pin - 1) & 3;
- irq_line = arch->irqs[irq_pin];
- pci_config_write8(addr, PCI_INTERRUPT_LINE, irq_line);
- config->irq_line = irq_line;
- } else
- config->irq_line = -1;
-}
-
-static void
-ob_pci_configure(pci_addr addr, pci_config_t *config, int num_regs, int rom_bar,
- unsigned long *mem_base, unsigned long *io_base)
-
-{
- uint32_t omask;
- uint16_t cmd;
- int reg;
- pci_addr config_addr;
-
- ob_pci_configure_irq(addr, config);
-
- omask = 0x00000000;
- for (reg = 0; reg < num_regs; ++reg) {
- config_addr = PCI_BASE_ADDR_0 + reg * 4;
-
- ob_pci_configure_bar(addr, config, reg, config_addr,
- &omask, mem_base,
- io_base);
- }
-
- if (rom_bar) {
- config_addr = rom_bar;
- ob_pci_configure_bar(addr, config, reg, config_addr,
- &omask, mem_base, io_base);
- }
- cmd = pci_config_read16(addr, PCI_COMMAND);
- cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
- pci_config_write16(addr, PCI_COMMAND, cmd);
-}
-
-static void ob_configure_pci_device(const char* parent_path,
- int *bus_num, unsigned long *mem_base, unsigned long *io_base,
- int bus, int devnum, int fn, int *p_is_multi);
-
-static void ob_scan_pci_bus(int *bus_num, unsigned long *mem_base,
- unsigned long *io_base, const char *path,
- int bus)
-{
- int devnum, fn, is_multi;
-
- PCI_DPRINTF("\nScanning bus %d at %s...\n", bus, path);
-
- for (devnum = 0; devnum < 32; devnum++) {
- is_multi = 0;
- for (fn = 0; fn==0 || (is_multi && fn<8); fn++) {
- ob_configure_pci_device(path, bus_num, mem_base, io_base,
- bus, devnum, fn, &is_multi);
-
- }
- }
-}
-
-static void ob_configure_pci_bridge(pci_addr addr,
- int *bus_num, unsigned long *mem_base,
- unsigned long *io_base,
- int primary_bus, pci_config_t *config)
-{
- config->primary_bus = primary_bus;
- pci_config_write8(addr, PCI_PRIMARY_BUS, config->primary_bus);
-
- config->secondary_bus = *bus_num;
- pci_config_write8(addr, PCI_SECONDARY_BUS, config->secondary_bus);
-
- config->subordinate_bus = 0xff;
- pci_config_write8(addr, PCI_SUBORDINATE_BUS, config->subordinate_bus);
-
- PCI_DPRINTF("scanning new pci bus %u under bridge %s\n",
- config->secondary_bus, config->path);
-
- /* make pci bridge parent device, prepare for recursion */
-
- ob_scan_pci_bus(bus_num, mem_base, io_base,
- config->path, config->secondary_bus);
-
- /* bus scan updates *bus_num to last revealed pci bus number */
- config->subordinate_bus = *bus_num;
- pci_config_write8(addr, PCI_SUBORDINATE_BUS, config->subordinate_bus);
-
- PCI_DPRINTF("bridge %s PCI bus primary=%d secondary=%d subordinate=%d\n",
- config->path, config->primary_bus, config->secondary_bus,
- config->subordinate_bus);
-
- pci_set_bus_range(config);
-}
-
-static int ob_pci_read_identification(int bus, int devnum, int fn,
- int *p_vid, int *p_did,
- uint8_t *p_class, uint8_t *p_subclass)
-{
- int vid, did;
- uint32_t ccode;
- pci_addr addr;
-
-#ifdef CONFIG_XBOX
- if (pci_xbox_blacklisted (bus, devnum, fn))
- return;
-#endif
- addr = PCI_ADDR(bus, devnum, fn);
- vid = pci_config_read16(addr, PCI_VENDOR_ID);
- did = pci_config_read16(addr, PCI_DEVICE_ID);
-
- if (vid==0xffff || vid==0) {
- return 0;
- }
-
- if (p_vid) {
- *p_vid = vid;
- }
-
- if (p_did) {
- *p_did = did;
- }
-
- ccode = pci_config_read16(addr, PCI_CLASS_DEVICE);
-
- if (p_class) {
- *p_class = ccode >> 8;
- }
-
- if (p_subclass) {
- *p_subclass = ccode;
- }
-
- return 1;
-}
-
-static void ob_configure_pci_device(const char* parent_path,
- int *bus_num, unsigned long *mem_base, unsigned long *io_base,
- int bus, int devnum, int fn, int *p_is_multi)
-{
- int vid, did;
- unsigned int htype;
- pci_addr addr;
- pci_config_t config = {};
- const pci_dev_t *pci_dev;
- uint8_t class, subclass, iface;
- int num_bars, rom_bar;
-
- phandle_t phandle = 0;
- int is_host_bridge = 0;
-
- if (!ob_pci_read_identification(bus, devnum, fn, &vid, &did, &class, &subclass)) {
- return;
- }
-
- addr = PCI_ADDR(bus, devnum, fn);
- iface = pci_config_read8(addr, PCI_CLASS_PROG);
-
- pci_dev = pci_find_device(class, subclass, iface,
- vid, did);
-
- PCI_DPRINTF("%x:%x.%x - %x:%x - ", bus, devnum, fn,
- vid, did);
-
- htype = pci_config_read8(addr, PCI_HEADER_TYPE);
-
- if (fn == 0) {
- if (p_is_multi) {
- *p_is_multi = htype & 0x80;
- }
- }
-
- /* stop adding host bridge accessible from it's primary bus
- PCI host bridge is to be added by host code
- */
- if (class == PCI_BASE_CLASS_BRIDGE &&
- subclass == PCI_SUBCLASS_BRIDGE_HOST) {
- is_host_bridge = 1;
- }
-
- if (is_host_bridge) {
- /* reuse device tree node */
- PCI_DPRINTF("host bridge found - ");
- snprintf(config.path, sizeof(config.path),
- "%s", parent_path);
- } else if (pci_dev == NULL || pci_dev->name == NULL) {
- snprintf(config.path, sizeof(config.path),
- "%s/pci%x,%x", parent_path, vid, did);
- }
- else {
- snprintf(config.path, sizeof(config.path),
- "%s/%s", parent_path, pci_dev->name);
- }
-
- PCI_DPRINTF("%s - ", config.path);
-
- config.dev = addr & 0x00FFFFFF;
-
- switch (class) {
- case PCI_BASE_CLASS_BRIDGE:
- if (subclass != PCI_SUBCLASS_BRIDGE_HOST) {
- REGISTER_NAMED_NODE_PHANDLE(ob_pci_bus_node, config.path, phandle);
- }
- break;
- case PCI_CLASS_DISPLAY:
- REGISTER_NAMED_NODE_PHANDLE(ob_pci_empty_node, config.path, phandle);
- break;
- default:
- REGISTER_NAMED_NODE_PHANDLE(ob_pci_simple_node, config.path, phandle);
- break;
- }
-
- if (is_host_bridge) {
- phandle = find_dev(config.path);
-
- if (get_property(phandle, "vendor-id", NULL)) {
- PCI_DPRINTF("host bridge already configured\n");
- return;
- }
- }
-
- activate_dev(phandle);
-
- if (htype & PCI_HEADER_TYPE_BRIDGE) {
- num_bars = 2;
- rom_bar = PCI_ROM_ADDRESS1;
- } else {
- num_bars = 6;
- rom_bar = PCI_ROM_ADDRESS;
- }
-
- ob_pci_configure(addr, &config, num_bars, rom_bar,
- mem_base, io_base);
-
- ob_pci_add_properties(phandle, addr, pci_dev, &config, num_bars);
-
- if (!is_host_bridge) {
- pci_set_reg(phandle, &config, num_bars);
- }
-
- /* call device-specific configuration callback */
- if (pci_dev && pci_dev->config_cb) {
- //activate_device(config.path);
- pci_dev->config_cb(&config);
- }
-
- /* device is configured so we may move it out of scope */
- device_end();
-
- /* scan bus behind bridge device */
- //if (htype & PCI_HEADER_TYPE_BRIDGE && class == PCI_BASE_CLASS_BRIDGE) {
- if ( class == PCI_BASE_CLASS_BRIDGE &&
- ( subclass == PCI_SUBCLASS_BRIDGE_PCI ||
- subclass == PCI_SUBCLASS_BRIDGE_HOST ) ) {
-
- if (subclass == PCI_SUBCLASS_BRIDGE_PCI) {
- /* reserve next pci bus number for this PCI bridge */
- ++(*bus_num);
- }
-
- ob_configure_pci_bridge(addr, bus_num, mem_base, io_base, bus, &config);
- }
-}
-
-static void ob_pci_set_available(phandle_t host, unsigned long mem_base, unsigned long io_base)
-{
- /* Create an available property for both memory and IO space */
- uint32_t props[10];
- int ncells;
-
- ncells = 0;
- ncells += pci_encode_phys_addr(props + ncells, 0, MEMORY_SPACE_32, 0, 0, mem_base);
- ncells += pci_encode_size(props + ncells, arch->mem_len - mem_base);
- ncells += pci_encode_phys_addr(props + ncells, 0, IO_SPACE, 0, 0, io_base);
- ncells += pci_encode_size(props + ncells, arch->io_len - io_base);
-
- set_property(host, "available", (char *)props, ncells * sizeof(props[0]));
-}
-
-/* Convert device/irq pin to interrupt property */
-#define SUN4U_INTERRUPT(dev, irq_pin) \
- ((((dev >> 11) << 2) + irq_pin - 1) & 0x1f)
-
-static void ob_pci_host_set_interrupt_map(phandle_t host)
-{
- phandle_t dnode = 0, pci_childnode = 0;
- u32 props[128], intno;
- int i, ncells, len;
- u32 *val, addr;
- char *reg;
-
-#if defined(CONFIG_PPC)
- phandle_t target_node;
-
- /* Oldworld macs do interrupt maps differently */
- if (!is_newworld())
- return;
-
- dnode = dt_iterate_type(0, "open-pic");
- if (dnode) {
- /* patch in openpic interrupt-parent properties */
- target_node = find_dev("/pci/mac-io");
- set_int_property(target_node, "interrupt-parent", dnode);
-
- target_node = find_dev("/pci/mac-io/escc/ch-a");
- set_int_property(target_node, "interrupt-parent", dnode);
-
- target_node = find_dev("/pci/mac-io/escc/ch-b");
- set_int_property(target_node, "interrupt-parent", dnode);
-
- target_node = find_dev("/pci/mac-io/escc-legacy/ch-a");
- set_int_property(target_node, "interrupt-parent", dnode);
-
- target_node = find_dev("/pci/mac-io/escc-legacy/ch-b");
- set_int_property(target_node, "interrupt-parent", dnode);
-
- /* QEMU only emulates 2 of the 3 ata buses currently */
- /* On a new world Mac these are not numbered but named by the
- * ATA version they support. Thus we have: ata-3, ata-3, ata-4
- * On g3beige they all called just ide.
- * We take 2 x ata-3 buses which seems to work for
- * at least the clients we care about */
- target_node = find_dev("/pci/mac-io/ata-3@20000");
- set_int_property(target_node, "interrupt-parent", dnode);
-
- target_node = find_dev("/pci/mac-io/ata-3@21000");
- set_int_property(target_node, "interrupt-parent", dnode);
-
- target_node = find_dev("/pci/mac-io/via-cuda");
- set_int_property(target_node, "interrupt-parent", dnode);
-
- target_node = find_dev("/pci");
- set_int_property(target_node, "interrupt-parent", dnode);
- }
-#else
- /* PCI host bridge is the default interrupt controller */
- dnode = host;
-#endif
-
- /* Set interrupt-map for PCI devices with an interrupt pin present */
- ncells = 0;
-
- PUSH(host);
- fword("child");
- pci_childnode = POP();
- while (pci_childnode) {
- intno = get_int_property(pci_childnode, "interrupts", &len);
- if (len && intno) {
- reg = get_property(pci_childnode, "reg", &len);
- if (len && reg) {
- val = (u32 *)reg;
-
- for (i = 0; i < (len / sizeof(u32)); i += 5) {
- addr = val[i];
-
- /* Device address is in 1st 32-bit word of encoded PCI address for config space */
- if ((addr & PCI_RANGE_TYPE_MASK) == PCI_RANGE_CONFIG) {
-#if defined(CONFIG_SPARC64)
- ncells += pci_encode_phys_addr(props + ncells, 0, 0, addr, 0, 0);
- props[ncells++] = intno;
- props[ncells++] = dnode;
- props[ncells++] = SUN4U_INTERRUPT(addr, intno);
-#elif defined(CONFIG_PPC)
- ncells += pci_encode_phys_addr(props + ncells, 0, 0, addr, 0, 0);
- props[ncells++] = intno;
- props[ncells++] = dnode;
- props[ncells++] = arch->irqs[intno - 1];
- props[ncells++] = 3;
-#else
- /* Keep compiler quiet */
- dnode = dnode;
-#endif
- }
- }
- }
- }
-
- PUSH(pci_childnode);
- fword("peer");
- pci_childnode = POP();
- }
- set_property(host, "interrupt-map", (char *)props, ncells * sizeof(props[0]));
-
- props[0] = 0x0000f800;
- props[1] = 0x0;
- props[2] = 0x0;
- props[3] = 0x7;
- set_property(host, "interrupt-map-mask", (char *)props, 4 * sizeof(props[0]));
-}
-
-int ob_pci_init(void)
-{
- int bus, devnum, fn;
- uint8_t class, subclass;
- unsigned long mem_base, io_base;
-
- pci_config_t config = {}; /* host bridge */
- phandle_t phandle_host = 0;
-
- PCI_DPRINTF("Initializing PCI host bridge...\n");
-
- activate_device("/");
-
- /* Find all PCI bridges */
-
- mem_base = arch->pci_mem_base;
- /* I/O ports under 0x400 are used by devices mapped at fixed
- location. */
- io_base = 0x400;
-
- bus = 0;
-
- for (devnum = 0; devnum < 32; devnum++) {
- /* scan only fn 0 */
- fn = 0;
-
- if (!ob_pci_read_identification(bus, devnum, fn,
- 0, 0, &class, &subclass)) {
- continue;
- }
-
- if (class != PCI_BASE_CLASS_BRIDGE || subclass != PCI_SUBCLASS_BRIDGE_HOST) {
- continue;
- }
-
- /* create root node for host PCI bridge */
-
- /* configure */
- snprintf(config.path, sizeof(config.path), "/pci");
-
- REGISTER_NAMED_NODE_PHANDLE(ob_pci_bus_node, config.path, phandle_host);
-
- pci_host_set_reg(phandle_host);
-
- /* update device path after changing "reg" property */
- ob_pci_reload_device_path(phandle_host, &config);
-
- ob_configure_pci_device(config.path, &bus, &mem_base, &io_base,
- bus, devnum, fn, 0);
-
- /* we expect single host PCI bridge
- but this may be machine-specific */
- break;
- }
-
- /* create available attributes for the PCI bridge */
- ob_pci_set_available(phandle_host, mem_base, io_base);
-
- /* configure the host bridge interrupt map */
- ob_pci_host_set_interrupt_map(phandle_host);
-
- device_end();
-
- return 0;
-}