diff options
author | Eric Biederman <ebiederm@xmission.com> | 2004-11-18 22:38:08 +0000 |
---|---|---|
committer | Eric Biederman <ebiederm@xmission.com> | 2004-11-18 22:38:08 +0000 |
commit | a9e632c2ac29c60872e7e4f9314263b34ce5031d (patch) | |
tree | 2a76647833896d68306553c548a65743c87b417e /src/arch | |
parent | bec8acedf18b4d35f95b4a4c254eb925bd4d53bd (diff) | |
download | coreboot-a9e632c2ac29c60872e7e4f9314263b34ce5031d.tar.xz |
- First stab at getting the ppc ports building and working.
- The sandpointx3+altimus has been consolidated into one directory for now.
- Added support for having different versions of the pci access functions
on a per bus basis if needed.
Hopefully I have not broken something inadvertently.
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1786 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/i386/boot/linuxbios_table.c | 3 | ||||
-rw-r--r-- | src/arch/i386/include/arch/pci_ops.h | 15 | ||||
-rw-r--r-- | src/arch/i386/lib/Config.lb | 2 | ||||
-rw-r--r-- | src/arch/i386/lib/exception.c | 2 | ||||
-rw-r--r-- | src/arch/i386/lib/pci_ops.c | 60 | ||||
-rw-r--r-- | src/arch/i386/lib/pci_ops_auto.c | 45 | ||||
-rw-r--r-- | src/arch/i386/lib/pci_ops_conf1.c | 19 | ||||
-rw-r--r-- | src/arch/i386/lib/pci_ops_conf2.c | 18 | ||||
-rw-r--r-- | src/arch/ppc/include/arch/cpu.h | 57 | ||||
-rw-r--r-- | src/arch/ppc/include/arch/pci_ops.h | 8 | ||||
-rw-r--r-- | src/arch/ppc/lib/Config.lb | 4 | ||||
-rw-r--r-- | src/arch/ppc/lib/c_start.S | 2 | ||||
-rw-r--r-- | src/arch/ppc/lib/cpu.c | 29 | ||||
-rw-r--r-- | src/arch/ppc/lib/div64.S | 58 | ||||
-rw-r--r-- | src/arch/ppc/lib/pci_ops.c | 105 | ||||
-rw-r--r-- | src/arch/ppc/lib/pci_ppc_conf1_ops.c | 46 |
16 files changed, 236 insertions, 237 deletions
diff --git a/src/arch/i386/boot/linuxbios_table.c b/src/arch/i386/boot/linuxbios_table.c index 594b5e55a9..5b2b34ff8a 100644 --- a/src/arch/i386/boot/linuxbios_table.c +++ b/src/arch/i386/boot/linuxbios_table.c @@ -315,7 +315,6 @@ static void build_lb_mem_range(void *gp, struct device *dev, struct resource *re static struct lb_memory *build_lb_mem(struct lb_header *head) { struct lb_memory *mem; - struct device *dev; /* Record where the lb memory ranges will live */ mem = lb_memory(head); @@ -343,7 +342,7 @@ unsigned long write_linuxbios_table( struct lb_record *rec_dest, *rec_src; /* Write the option config table... */ rec_dest = lb_new_record(head); - rec_src = (struct lb_record *)&option_table; + rec_src = (struct lb_record *)(void *)&option_table; memcpy(rec_dest, rec_src, rec_src->size); } /* Record where RAM is located */ diff --git a/src/arch/i386/include/arch/pci_ops.h b/src/arch/i386/include/arch/pci_ops.h index 51730c4692..72307a6211 100644 --- a/src/arch/i386/include/arch/pci_ops.h +++ b/src/arch/i386/include/arch/pci_ops.h @@ -1,18 +1,9 @@ #ifndef ARCH_I386_PCI_OPS_H #define ARCH_I386_PCI_OPS_H -struct pci_ops { - uint8_t (*read8) (uint8_t bus, int devfn, int where); - uint16_t (*read16) (uint8_t bus, int devfn, int where); - uint32_t (*read32) (uint8_t bus, int devfn, int where); - void (*write8) (uint8_t bus, int devfn, int where, uint8_t val); - void (*write16) (uint8_t bus, int devfn, int where, uint16_t val); - void (*write32) (uint8_t bus, int devfn, int where, uint32_t val); -}; -extern const struct pci_ops *conf; +const struct pci_bus_operations pci_cf8_conf1; +const struct pci_bus_operations pci_cf8_conf2; -void pci_set_method_conf1(void); -void pci_set_method_conf2(void); -void pci_set_method(void); +void pci_set_method(device_t dev); #endif /* ARCH_I386_PCI_OPS_H */ diff --git a/src/arch/i386/lib/Config.lb b/src/arch/i386/lib/Config.lb index 6de19b65be..cdd3fd3891 100644 --- a/src/arch/i386/lib/Config.lb +++ b/src/arch/i386/lib/Config.lb @@ -6,7 +6,7 @@ #option CONFIG_PCIBIOS_IRQ=0 object c_start.S object cpu.c -object pci_ops.c +#object pci_ops.c object pci_ops_conf1.c object pci_ops_conf2.c object pci_ops_auto.c diff --git a/src/arch/i386/lib/exception.c b/src/arch/i386/lib/exception.c index 86edccbdd2..5f0c4e0563 100644 --- a/src/arch/i386/lib/exception.c +++ b/src/arch/i386/lib/exception.c @@ -420,7 +420,7 @@ void x86_exception(struct eregs *info) if ( parse_ulong(&ptr, &addr) && (*ptr++ == ',') && parse_ulong(&ptr, &length)) { - copy_to_hex(out_buffer, addr, length); + copy_to_hex(out_buffer, (void *)addr, length); } else { memcpy(out_buffer, "E01", 4); } diff --git a/src/arch/i386/lib/pci_ops.c b/src/arch/i386/lib/pci_ops.c deleted file mode 100644 index ded7fd20a4..0000000000 --- a/src/arch/i386/lib/pci_ops.c +++ /dev/null @@ -1,60 +0,0 @@ -#include <console/console.h> -#include <arch/io.h> -#include <arch/pciconf.h> -#include <device/pci.h> -#include <device/pci_ids.h> -#include <device/pci_ops.h> - -const struct pci_ops *conf = 0; - -/* - * Direct access to PCI hardware... - */ - -uint8_t pci_read_config8(device_t dev, unsigned where) -{ - uint8_t value; - value = conf->read8(dev->bus->secondary, dev->path.u.pci.devfn, where); - printk_spew("Read config 8 bus %d,devfn 0x%x,reg 0x%x,val 0x%x\n", - dev->bus->secondary, dev->path.u.pci.devfn, where, value); - return value; -} - -uint16_t pci_read_config16(device_t dev, unsigned where) -{ - uint16_t value; - value = conf->read16(dev->bus->secondary, dev->path.u.pci.devfn, where); - printk_spew( "Read config 16 bus %d,devfn 0x%x,reg 0x%x,val 0x%x\n", - dev->bus->secondary, dev->path.u.pci.devfn, where, value); - return value; -} - -uint32_t pci_read_config32(device_t dev, unsigned where) -{ - uint32_t value; - value = conf->read32(dev->bus->secondary, dev->path.u.pci.devfn, where); - printk_spew( "Read config 32 bus %d,devfn 0x%x,reg 0x%x,val 0x%x\n", - dev->bus->secondary, dev->path.u.pci.devfn, where, value); - return value; -} - -void pci_write_config8(device_t dev, unsigned where, uint8_t val) -{ - printk_spew( "Write config 8 bus %d, devfn 0x%x, reg 0x%x, val 0x%x\n", - dev->bus->secondary, dev->path.u.pci.devfn, where, val); - conf->write8(dev->bus->secondary, dev->path.u.pci.devfn, where, val); -} - -void pci_write_config16(device_t dev, unsigned where, uint16_t val) -{ - printk_spew( "Write config 16 bus %d, devfn 0x%x, reg 0x%x, val 0x%x\n", - dev->bus->secondary, dev->path.u.pci.devfn, where, val); - conf->write16(dev->bus->secondary, dev->path.u.pci.devfn, where, val); -} - -void pci_write_config32(device_t dev, unsigned where, uint32_t val) -{ - printk_spew( "Write config 32 bus %d, devfn 0x%x, reg 0x%x, val 0x%x\n", - dev->bus->secondary, dev->path.u.pci.devfn, where, val); - conf->write32(dev->bus->secondary, dev->path.u.pci.devfn, where, val); -} diff --git a/src/arch/i386/lib/pci_ops_auto.c b/src/arch/i386/lib/pci_ops_auto.c index 5c45720888..b757e608fc 100644 --- a/src/arch/i386/lib/pci_ops_auto.c +++ b/src/arch/i386/lib/pci_ops_auto.c @@ -1,3 +1,4 @@ +#include <stddef.h> #include <console/console.h> #include <arch/io.h> #include <arch/pciconf.h> @@ -15,11 +16,12 @@ * This should be close to trivial, but it isn't, because there are buggy * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID. */ -static int pci_sanity_check(const struct pci_ops *o) +static int pci_sanity_check(const struct pci_bus_operations *o) { uint16_t class, vendor; - uint8_t bus; + unsigned bus; int devfn; + struct bus pbus; /* Dummy device */ #define PCI_CLASS_BRIDGE_HOST 0x0600 #define PCI_CLASS_DISPLAY_VGA 0x0300 #define PCI_VENDOR_ID_COMPAQ 0x0e11 @@ -27,8 +29,8 @@ static int pci_sanity_check(const struct pci_ops *o) #define PCI_VENDOR_ID_MOTOROLA 0x1057 for (bus = 0, devfn = 0; devfn < 0x100; devfn++) { - class = o->read16(bus, devfn, PCI_CLASS_DEVICE); - vendor = o->read16(bus, devfn, PCI_VENDOR_ID); + class = o->read16(&pbus, bus, devfn, PCI_CLASS_DEVICE); + vendor = o->read16(&pbus, bus, devfn, PCI_VENDOR_ID); if (((class == PCI_CLASS_BRIDGE_HOST) || (class == PCI_CLASS_DISPLAY_VGA)) || ((vendor == PCI_VENDOR_ID_INTEL) || (vendor == PCI_VENDOR_ID_COMPAQ) || (vendor == PCI_VENDOR_ID_MOTOROLA))) { @@ -39,7 +41,7 @@ static int pci_sanity_check(const struct pci_ops *o) return 0; } -static void pci_check_direct(void) +const struct pci_bus_operations *pci_check_direct(void) { unsigned int tmp; @@ -50,13 +52,12 @@ static void pci_check_direct(void) outb(0x01, 0xCFB); tmp = inl(0xCF8); outl(0x80000000, 0xCF8); - if (inl(0xCF8) == 0x80000000) { - pci_set_method_conf1(); - if (pci_sanity_check(conf)) { - outl(tmp, 0xCF8); - printk_debug("PCI: Using configuration type 1\n"); - return; - } + if ((inl(0xCF8) == 0x80000000) && + pci_sanity_check(&pci_cf8_conf1)) + { + outl(tmp, 0xCF8); + printk_debug("PCI: Using configuration type 1\n"); + return &pci_cf8_conf1; } outl(tmp, 0xCF8); } @@ -68,25 +69,23 @@ static void pci_check_direct(void) outb(0x00, 0xCFB); outb(0x00, 0xCF8); outb(0x00, 0xCFA); - if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00) { - pci_set_method_conf2(); - if (pci_sanity_check(conf)) { - printk_debug("PCI: Using configuration type 2\n"); - } + if ((inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00) && + pci_sanity_check(&pci_cf8_conf2)) + { + printk_debug("PCI: Using configuration type 2\n"); + return &pci_cf8_conf2; } } - printk_debug("pci_check_direct failed\n"); - conf = 0; - - return; + die("pci_check_direct failed\n"); + return NULL; } /** Set the method to be used for PCI, type I or type II */ -void pci_set_method(void) +void pci_set_method(device_t dev) { printk_info("Finding PCI configuration type.\n"); - pci_check_direct(); + dev->ops->ops_pci_bus = pci_check_direct(); post_code(0x5f); } diff --git a/src/arch/i386/lib/pci_ops_conf1.c b/src/arch/i386/lib/pci_ops_conf1.c index 1324add74a..fb0a434d53 100644 --- a/src/arch/i386/lib/pci_ops_conf1.c +++ b/src/arch/i386/lib/pci_ops_conf1.c @@ -10,37 +10,37 @@ #define CONFIG_CMD(bus,devfn, where) (0x80000000 | (bus << 16) | (devfn << 8) | (where & ~3)) -static uint8_t pci_conf1_read_config8(unsigned char bus, int devfn, int where) +static uint8_t pci_conf1_read_config8(struct bus *pbus, unsigned char bus, int devfn, int where) { outl(CONFIG_CMD(bus, devfn, where), 0xCF8); return inb(0xCFC + (where & 3)); } -static uint16_t pci_conf1_read_config16(unsigned char bus, int devfn, int where) +static uint16_t pci_conf1_read_config16(struct bus *pbus, unsigned char bus, int devfn, int where) { outl(CONFIG_CMD(bus, devfn, where), 0xCF8); return inw(0xCFC + (where & 2)); } -static uint32_t pci_conf1_read_config32(unsigned char bus, int devfn, int where) +static uint32_t pci_conf1_read_config32(struct bus *pbus, unsigned char bus, int devfn, int where) { outl(CONFIG_CMD(bus, devfn, where), 0xCF8); return inl(0xCFC); } -static void pci_conf1_write_config8(unsigned char bus, int devfn, int where, uint8_t value) +static void pci_conf1_write_config8(struct bus *pbus, unsigned char bus, int devfn, int where, uint8_t value) { outl(CONFIG_CMD(bus, devfn, where), 0xCF8); outb(value, 0xCFC + (where & 3)); } -static void pci_conf1_write_config16(unsigned char bus, int devfn, int where, uint16_t value) +static void pci_conf1_write_config16(struct bus *pbus, unsigned char bus, int devfn, int where, uint16_t value) { outl(CONFIG_CMD(bus, devfn, where), 0xCF8); outw(value, 0xCFC + (where & 2)); } -static void pci_conf1_write_config32(unsigned char bus, int devfn, int where, uint32_t value) +static void pci_conf1_write_config32(struct bus *pbus, unsigned char bus, int devfn, int where, uint32_t value) { outl(CONFIG_CMD(bus, devfn, where), 0xCF8); outl(value, 0xCFC); @@ -48,7 +48,7 @@ static void pci_conf1_write_config32(unsigned char bus, int devfn, int where, ui #undef CONFIG_CMD -static const struct pci_ops pci_direct_conf1 = +const struct pci_bus_operations pci_cf8_conf1 = { .read8 = pci_conf1_read_config8, .read16 = pci_conf1_read_config16, @@ -57,8 +57,3 @@ static const struct pci_ops pci_direct_conf1 = .write16 = pci_conf1_write_config16, .write32 = pci_conf1_write_config32, }; - -void pci_set_method_conf1(void) -{ - conf = &pci_direct_conf1; -} diff --git a/src/arch/i386/lib/pci_ops_conf2.c b/src/arch/i386/lib/pci_ops_conf2.c index 9fa03f18a8..10fde93346 100644 --- a/src/arch/i386/lib/pci_ops_conf2.c +++ b/src/arch/i386/lib/pci_ops_conf2.c @@ -12,7 +12,7 @@ #define FUNC(devfn) (((devfn & 7) << 1) | 0xf0) #define SET(bus,devfn) outb(FUNC(devfn), 0xCF8); outb(bus, 0xCFA); -static uint8_t pci_conf2_read_config8(unsigned char bus, int devfn, int where) +static uint8_t pci_conf2_read_config8(struct bus *pbus, unsigned char bus, int devfn, int where) { uint8_t value; SET(bus, devfn); @@ -21,7 +21,7 @@ static uint8_t pci_conf2_read_config8(unsigned char bus, int devfn, int where) return value; } -static uint16_t pci_conf2_read_config16(unsigned char bus, int devfn, int where) +static uint16_t pci_conf2_read_config16(struct bus *pbus, unsigned char bus, int devfn, int where) { uint16_t value; SET(bus, devfn); @@ -30,7 +30,7 @@ static uint16_t pci_conf2_read_config16(unsigned char bus, int devfn, int where) return value; } -static uint32_t pci_conf2_read_config32(unsigned char bus, int devfn, int where) +static uint32_t pci_conf2_read_config32(struct bus *pbus, unsigned char bus, int devfn, int where) { uint32_t value; SET(bus, devfn); @@ -39,21 +39,21 @@ static uint32_t pci_conf2_read_config32(unsigned char bus, int devfn, int where) return value; } -static void pci_conf2_write_config8(unsigned char bus, int devfn, int where, uint8_t value) +static void pci_conf2_write_config8(struct bus *pbus, unsigned char bus, int devfn, int where, uint8_t value) { SET(bus, devfn); outb(value, IOADDR(devfn, where)); outb(0, 0xCF8); } -static void pci_conf2_write_config16(unsigned char bus, int devfn, int where, uint16_t value) +static void pci_conf2_write_config16(struct bus *pbus, unsigned char bus, int devfn, int where, uint16_t value) { SET(bus, devfn); outw(value, IOADDR(devfn, where)); outb(0, 0xCF8); } -static void pci_conf2_write_config32(unsigned char bus, int devfn, int where, uint32_t value) +static void pci_conf2_write_config32(struct bus *pbus, unsigned char bus, int devfn, int where, uint32_t value) { SET(bus, devfn); outl(value, IOADDR(devfn, where)); @@ -64,7 +64,7 @@ static void pci_conf2_write_config32(unsigned char bus, int devfn, int where, ui #undef IOADDR #undef FUNC -static const struct pci_ops pci_direct_conf2 = +const struct pci_bus_operations pci_cf8_conf2 = { .read8 = pci_conf2_read_config8, .read16 = pci_conf2_read_config16, @@ -74,7 +74,3 @@ static const struct pci_ops pci_direct_conf2 = .write32 = pci_conf2_write_config32, }; -void pci_set_method_conf2(void) -{ - conf = &pci_direct_conf2; -} diff --git a/src/arch/ppc/include/arch/cpu.h b/src/arch/ppc/include/arch/cpu.h index 48293b2425..e0ed4ff66a 100644 --- a/src/arch/ppc/include/arch/cpu.h +++ b/src/arch/ppc/include/arch/cpu.h @@ -1,3 +1,60 @@ +#ifndef ARCH_CPU_H +#define ARCH_CPU_H /* * this should probably integrate code from src/arch/ppc/lib/cpuid.c */ + +struct cpu_device_id { + unsigned pvr; +}; + +struct cpu_driver { + struct device_operations *ops; + struct cpu_device_id *id_table; +}; + +#ifndef STACK_SIZE +#error STACK_SIZE not defined +#endif + +/* The basic logic comes from the Linux kernel. + * The invariant is that (1 << 31 - STACK_BITS) == STACK_SIZE + * I wish there was simpler way to support multiple stack sizes. + * Oh well. + */ +#if STACK_SIZE == 4096 +#define STACK_BITS "19" +#elif STACK_SIZE == 8192 +#define STACK_BITS "18" +#elif STACK_SIZE == 16384 +#define STACK_BITS "17" +#elif STACK_SIZE == 32768 +#define STACK_BITS "16" +#elif STACK_SIZE == 65536 +#define STACK_BITS "15" +#else +#error Unimplemented stack size +#endif + + +struct cpu_info { + struct device *cpu; + unsigned long index; +}; + + +static inline struct cpu_info *cpu_info(void) +{ + struct cpu_info *ci; + __asm__("rlwinm %0,1,0,0," STACK_BITS : "=r"(ci)); + return ci; +} + +static inline unsigned long cpu_index(void) +{ + struct cpu_info *ci; + ci = cpu_info(); + return ci->index; +} + +#endif /* ARCH_CPU_H */ diff --git a/src/arch/ppc/include/arch/pci_ops.h b/src/arch/ppc/include/arch/pci_ops.h index 6f9c3af3af..95f8941e42 100644 --- a/src/arch/ppc/include/arch/pci_ops.h +++ b/src/arch/ppc/include/arch/pci_ops.h @@ -1,6 +1,6 @@ -#ifndef ARCH_I386_PCI_OPS_H -#define ARCH_I386_PCI_OPS_H +#ifndef ARCH_PPC_PCI_OPS_H +#define ARCH_PPC_PCI_OPS_H -void pci_set_method(void); +const struct pci_bus_operations pci_ppc_conf1; -#endif /* ARCH_I386_PCI_OPS_H */ +#endif /* ARCH_PPC_PCI_OPS_H */ diff --git a/src/arch/ppc/lib/Config.lb b/src/arch/ppc/lib/Config.lb index 0c5aac9d5b..e501592683 100644 --- a/src/arch/ppc/lib/Config.lb +++ b/src/arch/ppc/lib/Config.lb @@ -1,15 +1,17 @@ object c_start.S object setup.o -object pci_ops.o +object pci_ppc_conf1_ops.o object pci_dev.o object timer.o object cpuid.o object cpu.o object timebase.S object floats.S +object div64.S initobject pci_dev.o initobject printk_init.o initobject timebase.S initobject timer.o initobject setup.o initobject floats.S +initobject div64.S diff --git a/src/arch/ppc/lib/c_start.S b/src/arch/ppc/lib/c_start.S index 3fcf840615..d0d2a8f3d7 100644 --- a/src/arch/ppc/lib/c_start.S +++ b/src/arch/ppc/lib/c_start.S @@ -17,6 +17,8 @@ _start: /* * init stack pointer to real ram now that memory is on + * Note: We use the last 8 bytes on the stack to hold struct cpu_info, + * Which are initialized to zero as we clear the stack. */ li r0, 0 lis r1, _estack@ha diff --git a/src/arch/ppc/lib/cpu.c b/src/arch/ppc/lib/cpu.c index adf5358c28..3b6a256908 100644 --- a/src/arch/ppc/lib/cpu.c +++ b/src/arch/ppc/lib/cpu.c @@ -1,12 +1,32 @@ #include <console/console.h> #include <arch/io.h> #include <string.h> +#include <device/device.h> #include <cpu/cpu.h> #include <cpu/ppc/cpuid.h> #include "ppc.h" #include "ppcreg.h" -#error "FIXME what should call cpu_initialize?" +#if 0 +static void set_cpu_ops(struct device *cpu) +{ + struct cpu_driver *driver; + cpu->ops = 0; + for (driver = cpu_drivers; driver < ecpu_drivers; driver++) { + struct cpu_device_id *id; + for(id = driver->id_table; id->pvr != 0; id++) { + if (cpu->device == id->pvr) + { + goto found; + } + } + } + die("Unknown cpu"); + return; + found: + cpu->ops = driver->ops; +} +#endif void cpu_initialize(void) { @@ -27,7 +47,7 @@ void cpu_initialize(void) } /* Find what type of cpu we are dealing with */ - cpu->vendor 0; /* PPC cpus do not have a vendor field */ + cpu->vendor = 0; /* PPC cpus do not have a vendor field */ cpu->device = ppc_getpvr(); display_cpuid(cpu); @@ -44,7 +64,6 @@ void cpu_initialize(void) #endif /* Turn on caching if we haven't already */ - printk_info("CPU #%d Initialized\n", processor_id); - return processor_id; + printk_info("CPU #%d Initialized\n", info->index); + return; } - diff --git a/src/arch/ppc/lib/div64.S b/src/arch/ppc/lib/div64.S new file mode 100644 index 0000000000..48047747e0 --- /dev/null +++ b/src/arch/ppc/lib/div64.S @@ -0,0 +1,58 @@ +/* + * Divide a 64-bit unsigned number by a 32-bit unsigned number. + * This routine assumes that the top 32 bits of the dividend are + * non-zero to start with. + * On entry, r3 points to the dividend, which get overwritten with + * the 64-bit quotient, and r4 contains the divisor. + * On exit, r3 contains the remainder. + * + * Copyright (C) 2002 Paul Mackerras, IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include <ppc_asm.tmpl> + + .globl __div64_32 +__div64_32: + lwz r5,0(r3) # get the dividend into r5/r6 + lwz r6,4(r3) + cmplw r5,r4 + li r7,0 + li r8,0 + blt 1f + divwu r7,r5,r4 # if dividend.hi >= divisor, + mullw r0,r7,r4 # quotient.hi = dividend.hi / divisor + subf. r5,r0,r5 # dividend.hi %= divisor + beq 3f +1: mr r11,r5 # here dividend.hi != 0 + andis. r0,r5,0xc000 + bne 2f + cntlzw r0,r5 # we are shifting the dividend right + li r10,-1 # to make it < 2^32, and shifting + srw r10,r10,r0 # the divisor right the same amount, + add r9,r4,r10 # rounding up (so the estimate cannot + andc r11,r6,r10 # ever be too large, only too small) + andc r9,r9,r10 + or r11,r5,r11 + rotlw r9,r9,r0 + rotlw r11,r11,r0 + divwu r11,r11,r9 # then we divide the shifted quantities +2: mullw r10,r11,r4 # to get an estimate of the quotient, + mulhwu r9,r11,r4 # multiply the estimate by the divisor, + subfc r6,r10,r6 # take the product from the divisor, + add r8,r8,r11 # and add the estimate to the accumulated + subfe. r5,r9,r5 # quotient + bne 1b +3: cmplw r6,r4 + blt 4f + divwu r0,r6,r4 # perform the remaining 32-bit division + mullw r10,r0,r4 # and get the remainder + add r8,r8,r0 + subf r6,r10,r6 +4: stw r7,0(r3) # return the quotient in *r3 + stw r8,4(r3) + mr r3,r6 # return the remainder in r3 + blr diff --git a/src/arch/ppc/lib/pci_ops.c b/src/arch/ppc/lib/pci_ops.c deleted file mode 100644 index 1e72fb0599..0000000000 --- a/src/arch/ppc/lib/pci_ops.c +++ /dev/null @@ -1,105 +0,0 @@ -#include <console/console.h> -#include <arch/pciconf.h> -#include <device/pci.h> -#include <device/pci_ids.h> -#include <device/pci_ops.h> - -static const struct pci_ops *conf; -struct pci_ops { - uint8_t (*read8) (uint8_t bus, int devfn, int where); - uint16_t (*read16) (uint8_t bus, int devfn, int where); - uint32_t (*read32) (uint8_t bus, int devfn, int where); - int (*write8) (uint8_t bus, int devfn, int where, uint8_t val); - int (*write16) (uint8_t bus, int devfn, int where, uint16_t val); - int (*write32) (uint8_t bus, int devfn, int where, uint32_t val); -}; - -struct pci_ops pci_direct_ppc; - -/* - * Before we decide to use direct hardware access mechanisms, we try to do some - * trivial checks to ensure it at least _seems_ to be working -- we just test - * whether bus 00 contains a host bridge (this is similar to checking - * techniques used in XFree86, but ours should be more reliable since we - * attempt to make use of direct access hints provided by the PCI BIOS). - * - * This should be close to trivial, but it isn't, because there are buggy - * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID. - */ -static int pci_sanity_check(const struct pci_ops *o) -{ - uint16_t class, vendor; - uint8_t bus; - int devfn; -#define PCI_CLASS_BRIDGE_HOST 0x0600 -#define PCI_CLASS_DISPLAY_VGA 0x0300 -#define PCI_VENDOR_ID_COMPAQ 0x0e11 -#define PCI_VENDOR_ID_INTEL 0x8086 -#define PCI_VENDOR_ID_MOTOROLA 0x1057 -#define PCI_VENDOR_ID_IBM 0x1014 - - for (bus = 0, devfn = 0; devfn < 0x100; devfn++) { - class = o->read16(bus, devfn, PCI_CLASS_DEVICE); - vendor = o->read16(bus, devfn, PCI_VENDOR_ID); - if (((class == PCI_CLASS_BRIDGE_HOST) || - (class == PCI_CLASS_DISPLAY_VGA)) || - ((vendor == PCI_VENDOR_ID_INTEL) || - (vendor == PCI_VENDOR_ID_COMPAQ) || - (vendor == PCI_VENDOR_ID_MOTOROLA) || - (vendor == PCI_VENDOR_ID_IBM))) { - return 1; - } - } - - printk_err("PCI: Sanity check failed\n"); - return 0; -} - -uint8_t pci_read_config8(device_t dev, unsigned where) -{ - return conf->read8(dev->bus->secondary, dev->path.u.pci.devfn, where); -} - -uint16_t pci_read_config16(struct device *dev, unsigned where) -{ - return conf->read16(dev->bus->secondary, dev->path.u.pci.devfn, where); -} - -uint32_t pci_read_config32(struct device *dev, unsigned where) -{ - return conf->read32(dev->bus->secondary, dev->path.u.pci.devfn, where); -} - -void pci_write_config8(struct device *dev, unsigned where, uint8_t val) -{ - conf->write8(dev->bus->secondary, dev->path.u.pci.devfn, where, val); -} - -void pci_write_config16(struct device *dev, unsigned where, uint16_t val) -{ - conf->write16(dev->bus->secondary, dev->path.u.pci.devfn, where, val); -} - -void pci_write_config32(struct device *dev, unsigned where, uint32_t val) -{ - conf->write32(dev->bus->secondary, dev->path.u.pci.devfn, where, val); -} - -/** Set the method to be used for PCI - */ -void pci_set_method(void) -{ - conf = &pci_direct_ppc; - pci_sanity_check(conf); -} - -struct pci_ops pci_direct_ppc = -{ - pci_ppc_read_config8, - pci_ppc_read_config16, - pci_ppc_read_config32, - pci_ppc_write_config8, - pci_ppc_write_config16, - pci_ppc_write_config32 -}; - diff --git a/src/arch/ppc/lib/pci_ppc_conf1_ops.c b/src/arch/ppc/lib/pci_ppc_conf1_ops.c new file mode 100644 index 0000000000..12e4529784 --- /dev/null +++ b/src/arch/ppc/lib/pci_ppc_conf1_ops.c @@ -0,0 +1,46 @@ +#include <console/console.h> +#include <arch/pciconf.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> + +static uint8_t ppc_conf1_read_config8(struct bus *pbus, unsigned char bus, int devfn, int where) +{ + return pci_ppc_read_config8(bus, devfn, where); +} + +static uint16_t ppc_conf1_read_config16(struct bus *pbus, unsigned char bus, int devfn, int where) +{ + return pci_ppc_read_config16(bus, devfn, where); +} + +static uint32_t ppc_conf1_read_config32(struct bus *pbus, unsigned char bus, int devfn, int where) +{ + return pci_ppc_read_config32(bus, devfn, where); +} + +static void ppc_conf1_write_config8(struct bus *pbus, unsigned char bus, int devfn, int where, uint8_t val) +{ + pci_ppc_write_config8(bus, devfn, where, val); +} + +static void ppc_conf1_write_config16(struct bus *pbus, unsigned char bus, int devfn, int where, uint16_t val) +{ + pci_ppc_write_config16(bus, devfn, where, val); +} + +static void ppc_conf1_write_config32(struct bus *pbus, unsigned char bus, int devfn, int where, uint32_t val) +{ + pci_ppc_write_config32(bus, devfn, where, val); +} + +const struct pci_bus_operations pci_ppc_conf1 = +{ + .read8 = ppc_conf1_read_config8, + .read16 = ppc_conf1_read_config16, + .read32 = ppc_conf1_read_config32, + .write8 = ppc_conf1_write_config8, + .write16 = ppc_conf1_write_config16, + .write32 = ppc_conf1_write_config32, +}; |