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 | |
parent | bec8acedf18b4d35f95b4a4c254eb925bd4d53bd (diff) |
- 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
62 files changed, 1467 insertions, 322 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, +}; diff --git a/src/cpu/ppc/mpc74xx/Config.lb b/src/cpu/ppc/mpc74xx/Config.lb index f9d5b407d4..8665fa35c0 100644 --- a/src/cpu/ppc/mpc74xx/Config.lb +++ b/src/cpu/ppc/mpc74xx/Config.lb @@ -19,3 +19,5 @@ initinclude "FAMILY_INIT" cpu/ppc/mpc74xx/mpc74xx.inc object cache.S initobject cache.S +dir /cpu/simple_init + diff --git a/src/cpu/ppc/ppc4xx/Config.lb b/src/cpu/ppc/ppc4xx/Config.lb index e9e45c5aa3..353c25df2c 100644 --- a/src/cpu/ppc/ppc4xx/Config.lb +++ b/src/cpu/ppc/ppc4xx/Config.lb @@ -24,3 +24,4 @@ object mem.o object clock.o object cache.S +dir /cpu/simple_init diff --git a/src/cpu/ppc/ppc7xx/Config.lb b/src/cpu/ppc/ppc7xx/Config.lb index ec606552f1..dc2c025511 100644 --- a/src/cpu/ppc/ppc7xx/Config.lb +++ b/src/cpu/ppc/ppc7xx/Config.lb @@ -21,3 +21,5 @@ object clock.o object cache.S initobject clock.o initobject cache.S + +dir /cpu/simple_init diff --git a/src/cpu/simple_init/simple_cpu_init.c b/src/cpu/simple_init/simple_cpu_init.c index 02eb73f391..e0a80c6820 100644 --- a/src/cpu/simple_init/simple_cpu_init.c +++ b/src/cpu/simple_init/simple_cpu_init.c @@ -1,7 +1,7 @@ -#include <linux/console.h> +#include <console/console.h> #include <device/device.h> #include <device/path.h> -#include <device/cpu.h> +#include <cpu/cpu.h> #if CONFIG_SMP #error "This Configuration does not support SMP" @@ -16,10 +16,11 @@ void initialize_cpus(struct bus *cpu_bus) info = cpu_info(); /* Get the device path of the boot cpu */ - cpu_path.type = DEVICE_PATH_BOOT_CPU; + cpu_path.type = DEVICE_PATH_CPU; + cpu_path.u.cpu.id = 0; /* Find the device struct for the boot cpu */ - info->cpu = alloc_find_dev(bus, &cpu_path); + info->cpu = alloc_find_dev(cpu_bus, &cpu_path); /* Initialize the bootstrap processor */ cpu_initialize(); diff --git a/src/cpu/x86/lapic/lapic_cpu_init.c b/src/cpu/x86/lapic/lapic_cpu_init.c index 5e7b7934c7..b477d1f0cc 100644 --- a/src/cpu/x86/lapic/lapic_cpu_init.c +++ b/src/cpu/x86/lapic/lapic_cpu_init.c @@ -301,7 +301,8 @@ void initialize_cpus(struct bus *cpu_bus) cpu_path.u.apic.apic_id = lapicid(); #else /* Get the device path of the boot cpu */ - cpu_path.type = DEVICE_PATH_DEFAULT_CPU; + cpu_path.type = DEVICE_PATH_CPU; + cpu_path.u.cpu.id = 0; #endif /* Find the device structure for the boot cpu */ diff --git a/src/devices/Config.lb b/src/devices/Config.lb index 80b64a0d44..12a31091d0 100644 --- a/src/devices/Config.lb +++ b/src/devices/Config.lb @@ -4,3 +4,4 @@ object device_util.o object pci_device.o object pnp_device.o object hypertransport.o +object pci_ops.o diff --git a/src/devices/device_util.c b/src/devices/device_util.c index fd8fdcf9b8..6af2d3786f 100644 --- a/src/devices/device_util.c +++ b/src/devices/device_util.c @@ -114,9 +114,6 @@ const char *dev_path(device_t dev) case DEVICE_PATH_ROOT: memcpy(buffer, "Root Device", 12); break; - case DEVICE_PATH_DEFAULT_CPU: - memcpy(buffer, "Default CPU", 12); - break; case DEVICE_PATH_PCI: sprintf(buffer, "PCI: %02x:%02x.%01x", dev->bus->secondary, @@ -142,6 +139,12 @@ const char *dev_path(device_t dev) sprintf(buffer, "APIC_CLUSTER: %01x", dev->path.u.apic_cluster.cluster); break; + case DEVICE_PATH_CPU: + sprintf(buffer, "CPU: %02x", dev->path.u.cpu.id); + break; + case DEVICE_PATH_CPU_BUS: + sprintf(buffer, "CPU_BUS: %02x", dev->path.u.cpu_bus.id); + break; default: printk_err("Unknown device path type: %d\n", dev->path.type); break; @@ -160,9 +163,6 @@ int path_eq(struct device_path *path1, struct device_path *path2) case DEVICE_PATH_ROOT: equal = 1; break; - case DEVICE_PATH_DEFAULT_CPU: - equal = 1; - break; case DEVICE_PATH_PCI: equal = (path1->u.pci.devfn == path2->u.pci.devfn); break; @@ -182,6 +182,12 @@ int path_eq(struct device_path *path1, struct device_path *path2) case DEVICE_PATH_APIC_CLUSTER: equal = (path1->u.apic_cluster.cluster == path2->u.apic_cluster.cluster); break; + case DEVICE_PATH_CPU: + equal = (path1->u.cpu.id == path2->u.cpu.id); + break; + case DEVICE_PATH_CPU_BUS: + equal = (path1->u.cpu_bus.id == path2->u.cpu_bus.id); + break; default: printk_err("Uknown device type: %d\n", path1->type); break; diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c index 1c8c8bea84..bd5e2775fe 100644 --- a/src/devices/pci_device.c +++ b/src/devices/pci_device.c @@ -480,7 +480,7 @@ void pci_dev_set_resources(struct device *dev) void pci_dev_enable_resources(struct device *dev) { - struct pci_operations *ops; + const struct pci_operations *ops; uint16_t command; /* Set the subsystem vendor and device id for mainboard devices */ @@ -515,6 +515,7 @@ void pci_bus_enable_resources(struct device *dev) enable_childrens_resources(dev); } + void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device) { pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, @@ -522,7 +523,7 @@ void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device) } /** Default device operation for PCI devices */ -static struct pci_operations pci_ops_pci_dev = { +static struct pci_operations pci_dev_ops_pci = { .set_subsystem = pci_dev_set_subsystem, }; @@ -533,11 +534,11 @@ struct device_operations default_pci_ops_dev = { .init = 0, .scan_bus = 0, .enable = 0, - .ops_pci = &pci_ops_pci_dev, + .ops_pci = &pci_dev_ops_pci, }; /** Default device operations for PCI bridges */ -static struct pci_operations pci_ops_pci_bus = { +static struct pci_operations pci_bus_ops_pci = { .set_subsystem = 0, }; struct device_operations default_pci_ops_bus = { @@ -547,7 +548,7 @@ struct device_operations default_pci_ops_bus = { .init = 0, .scan_bus = pci_scan_bridge, .enable = 0, - .ops_pci = &pci_ops_pci_bus, + .ops_pci = &pci_bus_ops_pci, }; /** @@ -857,6 +858,7 @@ unsigned int pci_scan_bridge(struct device *dev, unsigned int max) uint16_t cr; bus = &dev->link[0]; + bus->dev = dev; dev->links = 1; /* Set up the primary, secondary and subordinate bus numbers. We have diff --git a/src/devices/pci_ops.c b/src/devices/pci_ops.c new file mode 100644 index 0000000000..441b328e0f --- /dev/null +++ b/src/devices/pci_ops.c @@ -0,0 +1,55 @@ +#include <console/console.h> +#include <arch/pciconf.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> + +static struct bus *get_pbus(device_t dev) +{ + struct bus *pbus = dev->bus; + while(pbus && pbus->dev && !ops_pci_bus(pbus)) { + pbus = pbus->dev->bus; + } + if (!pbus || !pbus->dev || !pbus->dev->ops || !pbus->dev->ops->ops_pci_bus) { + printk_alert("%s Cannot find pci bus operations", dev_path(dev)); + die(""); + for(;;); + } + return pbus; +} + +uint8_t pci_read_config8(device_t dev, unsigned where) +{ + struct bus *pbus = get_pbus(dev); + return ops_pci_bus(pbus)->read8(pbus, dev->bus->secondary, dev->path.u.pci.devfn, where); +} + +uint16_t pci_read_config16(device_t dev, unsigned where) +{ + struct bus *pbus = get_pbus(dev); + return ops_pci_bus(pbus)->read16(pbus, dev->bus->secondary, dev->path.u.pci.devfn, where); +} + +uint32_t pci_read_config32(device_t dev, unsigned where) +{ + struct bus *pbus = get_pbus(dev); + return ops_pci_bus(pbus)->read32(pbus, dev->bus->secondary, dev->path.u.pci.devfn, where); +} + +void pci_write_config8(device_t dev, unsigned where, uint8_t val) +{ + struct bus *pbus = get_pbus(dev); + ops_pci_bus(pbus)->write8(pbus, dev->bus->secondary, dev->path.u.pci.devfn, where, val); +} + +void pci_write_config16(device_t dev, unsigned where, uint16_t val) +{ + struct bus *pbus = get_pbus(dev); + ops_pci_bus(pbus)->write16(pbus, dev->bus->secondary, dev->path.u.pci.devfn, where, val); +} + +void pci_write_config32(device_t dev, unsigned where, uint32_t val) +{ + struct bus *pbus = get_pbus(dev); + ops_pci_bus(pbus)->write32(pbus, dev->bus->secondary, dev->path.u.pci.devfn, where, val); +} diff --git a/src/include/arch-generic/div64.h b/src/include/arch-generic/div64.h index 4015810d8c..08db225d3f 100644 --- a/src/include/arch-generic/div64.h +++ b/src/include/arch-generic/div64.h @@ -33,7 +33,7 @@ extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor); uint32_t __base = (base); \ uint32_t __rem; \ (void)(((typeof((n)) *)0) == ((uint64_t *)0)); \ - if (likely(((n) >> 32) == 0)) { \ + if (((n) >> 32) == 0) { \ __rem = (uint32_t)(n) % __base; \ (n) = (uint32_t)(n) / __base; \ } else \ diff --git a/src/include/cpu/cpu.h b/src/include/cpu/cpu.h index e211d990e0..468af24850 100644 --- a/src/include/cpu/cpu.h +++ b/src/include/cpu/cpu.h @@ -2,6 +2,7 @@ #define CPU_CPU_H struct device; +struct bus; #include <arch/cpu.h> void cpu_initialize(void); diff --git a/src/include/cpu/ppc/cpuid.h b/src/include/cpu/ppc/cpuid.h index 8a497dfd11..3ef065b601 100644 --- a/src/include/cpu/ppc/cpuid.h +++ b/src/include/cpu/ppc/cpuid.h @@ -1,6 +1,6 @@ #ifndef CPU_PPC_CPUID_H #define CPU_PPC_CPUID_H -void display_cpuid(void); +void display_cpuid(device_t dev); #endif /* CPU_PPC_CPUID_H */ diff --git a/src/include/device/device.h b/src/include/device/device.h index 945cdaabe3..db91fcc1ef 100644 --- a/src/include/device/device.h +++ b/src/include/device/device.h @@ -9,6 +9,7 @@ struct device; typedef struct device * device_t; struct pci_operations; +struct pci_bus_operations; struct smbus_bus_operations; /* Chip operations */ @@ -30,10 +31,11 @@ struct device_operations { void (*set_resources)(device_t dev); void (*enable_resources)(device_t dev); void (*init)(device_t dev); - unsigned int (*scan_bus)(device_t bus, unsigned int max); + unsigned int (*scan_bus)(device_t bus, unsigned int max); void (*enable)(device_t dev); - struct pci_operations *ops_pci; - struct smbus_bus_operations *ops_smbus_bus; + const struct pci_operations *ops_pci; + const struct smbus_bus_operations *ops_smbus_bus; + const struct pci_bus_operations *ops_pci_bus; }; diff --git a/src/include/device/path.h b/src/include/device/path.h index cdb98ee8a8..f55827b9c0 100644 --- a/src/include/device/path.h +++ b/src/include/device/path.h @@ -4,13 +4,14 @@ enum device_path_type { DEVICE_PATH_NONE = 0, DEVICE_PATH_ROOT, - DEVICE_PATH_DEFAULT_CPU, DEVICE_PATH_PCI, DEVICE_PATH_PNP, DEVICE_PATH_I2C, DEVICE_PATH_APIC, DEVICE_PATH_PCI_DOMAIN, DEVICE_PATH_APIC_CLUSTER, + DEVICE_PATH_CPU, + DEVICE_PATH_CPU_BUS, }; struct pci_domain_path @@ -44,16 +45,28 @@ struct apic_cluster_path unsigned cluster; }; +struct cpu_path +{ + unsigned id; +}; + +struct cpu_bus_path +{ + unsigned id; +}; + struct device_path { enum device_path_type type; union { - struct pci_path pci; - struct pnp_path pnp; - struct i2c_path i2c; - struct apic_path apic; - struct pci_domain_path pci_domain; + struct pci_path pci; + struct pnp_path pnp; + struct i2c_path i2c; + struct apic_path apic; + struct pci_domain_path pci_domain; struct apic_cluster_path apic_cluster; + struct cpu_path cpu; + struct cpu_bus_path cpu_bus; } u; }; diff --git a/src/include/device/pci.h b/src/include/device/pci.h index 228d4f6e7e..2c9797fa6c 100644 --- a/src/include/device/pci.h +++ b/src/include/device/pci.h @@ -26,6 +26,16 @@ struct pci_operations { void (*set_subsystem)(device_t dev, unsigned vendor, unsigned device); }; +/* Common pci bus operations */ +struct pci_bus_operations { + uint8_t (*read8) (struct bus *pbus, unsigned char bus, int devfn, int where); + uint16_t (*read16) (struct bus *pbus, unsigned char bus, int devfn, int where); + uint32_t (*read32) (struct bus *pbus, unsigned char bus, int devfn, int where); + void (*write8) (struct bus *pbus, unsigned char bus, int devfn, int where, uint8_t val); + void (*write16) (struct bus *pbus, unsigned char bus, int devfn, int where, uint16_t val); + void (*write32) (struct bus *pbus, unsigned char bus, int devfn, int where, uint32_t val); +}; + struct pci_driver { struct device_operations *ops; unsigned short vendor; @@ -55,9 +65,9 @@ void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device); #define PCI_IO_BRIDGE_ALIGN 4096 #define PCI_MEM_BRIDGE_ALIGN (1024*1024) -static inline struct pci_operations *ops_pci(device_t dev) +static inline const struct pci_operations *ops_pci(device_t dev) { - struct pci_operations *pops; + const struct pci_operations *pops; pops = 0; if (dev && dev->ops) { pops = dev->ops->ops_pci; @@ -65,4 +75,14 @@ static inline struct pci_operations *ops_pci(device_t dev) return pops; } +static inline const struct pci_bus_operations *ops_pci_bus(struct bus *bus) +{ + const struct pci_bus_operations *bops; + bops = 0; + if (bus && bus->dev && bus->dev->ops) { + bops = bus->dev->ops->ops_pci_bus; + } + return bops; +} + #endif /* PCI_H */ diff --git a/src/mainboard/motorola/sandpoint/Config.lb b/src/mainboard/motorola/sandpoint/Config.lb index 94e0ba79f1..216670f174 100644 --- a/src/mainboard/motorola/sandpoint/Config.lb +++ b/src/mainboard/motorola/sandpoint/Config.lb @@ -20,30 +20,30 @@ object clock.o arch ppc end if CONFIG_SANDPOINT_ALTIMUS - chip pmc/altimus/mpc7410 device pnp 0.0 on end end -# chip pmc/altimus/mpc7400 device pnp 0.0 on end end -# chip pmc/altimus/mpc75x device pnp 0.0 on end end + dir /pmc/altimus/mpc7410 +# dir /pmc/altimus/mpc7400 +# dir /pmc/altimus/mpc75x end if CONFIG_SANDPOINT_TALUS - chip pmc/talus/mpc74x device pnp 0.0 on end end - chip pmc/talus/mpc603 device pnp 0.0 on end end + dir /pmc/talus/mpc74x + dir /pmc/talus/mpc603 end if CONFIG_SANDPOINT_UNITY - chip pmc/unity/mpc824x device pnp 0.0 on end end + dir /pmc/unity/mpc824x end if CONFIG_SANDPOINT_VALIS - chip pmc/valis/mpc745x device pnp 0.0 on end end + dir /pmc/valis/mpc745x end if CONFIG_SANDPOINT_GYRUS - chip pmc/gyrus/mpc744x device pnp 0.0 on end end + dir /pmc/gyrus/mpc744x end ## ## Include the secondary Configuration files ## -chip southbridge/winbond/w83c553 device pnp 0.0 on end end +dir /southbridge/winbond/w83c553 -chip superio/NSC/pc97307 device pnp 0.0 on end end +dir /superio/NSC/pc97307 ## ## Build the objects we have code for in this directory. diff --git a/src/mainboard/motorola/sandpointx3_altimus_mpc7410/Config.lb b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/Config.lb new file mode 100644 index 0000000000..bbb8c2c131 --- /dev/null +++ b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/Config.lb @@ -0,0 +1,64 @@ +## +## Config file for the Motorola Sandpoint III development system. +## Note that this has only been tested with the Altimus 7410 PMC. +## + +## +## Early board initialization, called from ppc_main() +## +initobject init.o +initobject clock.o + +## +## Stage 2 timer support +## +object clock.o + +## +## Set our ARCH +## +arch ppc end + +## +## Build the objects we have code for in this directory. +## +#object mpc7410.o + +chip northbridge/motorola/mpc107 + device pci_domain 0 on + device pci 0.0 on + chip southbridge/winbond/w83c553 + # FIXME The function numbers are ok but the device id is wrong here! + device pci 0.0 on + chip superio/NSC/pc97307 + device pnp 2e.0 on end # Kyeboard + device pnp 2e.1 on end # Mouse + device pnp 2e.2 on end # Real-time Clock + device pnp 2e.3 on end # Floppy + device pnp 2e.4 on end # Parallel port + device pnp 2e.5 on end # com2 + device pnp 2e.6 on end # com1 + device pnp 2e.7 on end # gpio + device pnp 2e.8 on end # Power management + end + end # pci to isa bridge + device pci 0.1 on end # pci ide controller + end + end + end + device cpu_bus 0 on + chip cpu/ppc/mpc74xx + device cpu 0 on end + end + end +end + +## +## Build the objects we have code for in this directory. +## + +dir nvram +dir flash + +addaction linuxbios.a "$(CROSS_COMPILE)ranlib linuxbios.a" +makedefine CFLAGS += -g diff --git a/src/mainboard/motorola/sandpointx3_altimus_mpc7410/Options.lb b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/Options.lb new file mode 100644 index 0000000000..f17fc0ef82 --- /dev/null +++ b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/Options.lb @@ -0,0 +1,122 @@ +uses CONFIG_SANDPOINT_ALTIMUS +uses CONFIG_SANDPOINT_TALUS +uses CONFIG_SANDPOINT_UNITY +uses CONFIG_SANDPOINT_VALIS +uses CONFIG_SANDPOINT_GYRUS +uses ISA_IO_BASE +uses ISA_MEM_BASE +uses PCIC0_CFGADDR +uses PCIC0_CFGDATA +uses PNP_CFGADDR +uses PNP_CFGDATA +uses _IO_BASE + +uses CROSS_COMPILE +uses HAVE_OPTION_TABLE +uses CONFIG_SANDPOINT_ALTIMUS +uses CONFIG_COMPRESS +uses DEFAULT_CONSOLE_LOGLEVEL +uses CONFIG_USE_INIT +uses CONFIG_CHIP_CONFIGURE +uses NO_POST +uses CONFIG_CONSOLE_SERIAL8250 +uses TTYS0_BASE +uses CONFIG_IDE +uses CONFIG_FS_STREAM +uses CONFIG_FS_EXT2 +uses CONFIG_FS_ISO9660 +uses CONFIG_FS_FAT +uses AUTOBOOT_CMDLINE +uses PAYLOAD_SIZE +uses ROM_SIZE +uses ROM_IMAGE_SIZE +uses _RESET +uses _EXCEPTION_VECTORS +uses _ROMBASE +uses _ROMSTART +uses _RAMBASE +uses _RAMSTART +uses STACK_SIZE +uses HEAP_SIZE + +uses MAINBOARD +uses MAINBOARD_VENDOR +uses MAINBOARD_PART_NUMBER +uses LINUXBIOS_EXTRA_VERSION +uses CROSS_COMPILE +uses CC +uses HOSTCC +uses OBJCOPY + +## +## Set memory map +## +default ISA_IO_BASE=0xfe000000 +default ISA_MEM_BASE=0xfd000000 +default PCIC0_CFGADDR=0xfec00000 +default PCIC0_CFGDATA=0xfee00000 +default PNP_CFGADDR=0x15c +default PNP_CFGDATA=0x15d +default _IO_BASE=ISA_IO_BASE + + +## use a cross compiler +#default CROSS_COMPILE="powerpc-eabi-" +#default CROSS_COMPILE="ppc_74xx-" + +## Use stage 1 initialization code +default CONFIG_USE_INIT=1 + +## Use static configuration +default CONFIG_CHIP_CONFIGURE=1 + +## We don't use compressed image +default CONFIG_COMPRESS=0 + +## Turn off POST codes +default NO_POST=1 + +## Enable serial console +default DEFAULT_CONSOLE_LOGLEVEL=8 +default CONFIG_CONSOLE_SERIAL8250=1 +default TTYS0_BASE=0x3f8 + +## Load payload using filo +default CONFIG_IDE=1 +default CONFIG_FS_STREAM=1 +default CONFIG_FS_EXT2=1 +default CONFIG_FS_ISO9660=1 +default CONFIG_FS_FAT=1 +default AUTOBOOT_CMDLINE="hdc1:/vmlinuz" + +# LinuxBIOS must fit into 128KB +default ROM_IMAGE_SIZE=131072 +default ROM_SIZE={ROM_IMAGE_SIZE+PAYLOAD_SIZE} +default PAYLOAD_SIZE=262144 + +# Set stack and heap sizes (stage 2) +default STACK_SIZE=0x10000 +default HEAP_SIZE=0x10000 + +# Sandpoint Demo Board +## Base of ROM +default _ROMBASE=0xfff00000 + +## Sandpoint reset vector +default _RESET=_ROMBASE+0x100 + +## Exception vectors (other than reset vector) +default _EXCEPTION_VECTORS=_RESET+0x100 + +## Start of linuxBIOS in the boot rom +## = _RESET + exeception vector table size +default _ROMSTART=_RESET+0x3100 + +## LinuxBIOS C code runs at this location in RAM +default _RAMBASE=0x00100000 +default _RAMSTART=0x00100000 + +default CONFIG_SANDPOINT_ALTIMUS=1 + +### End Options.lb +end diff --git a/src/mainboard/motorola/sandpointx3_altimus_mpc7410/STATUS b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/STATUS new file mode 100644 index 0000000000..1f528e38da --- /dev/null +++ b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/STATUS @@ -0,0 +1,27 @@ +# These are keyword-value pairs. +# a : separates the keyword from the value +# the value is arbitrary text delimited by newline. +# continuation, if needed, will be via the \ at the end of a line +# comments are indicated by a '#' as the first character. +# the keywords are case-INSENSITIVE +owner: Greg Watson +email: gwatson@lanl.gov +#status: One of unsupported, unstable, stable +status: unstable +explanation: currently under development +flash-types: +payload-types: +# e.g. linux, plan 9, wince, etc. +OS-types: linux +# e.g. "Plan 9 interrupts don't work on this chipset" +OS-issues: +console-types: serial +# vga is unsupported, unstable, or stable +vga: unsupported +# Last-known-good follows the internationl date standard: day/month/year +last-known-good: 19/04/2003 +Comments: +Links: +Mainboard-revision: +# What other mainboards are like this one? List them here. +AKA: diff --git a/src/mainboard/motorola/sandpointx3_altimus_mpc7410/clock.c b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/clock.c new file mode 100644 index 0000000000..91c387ee03 --- /dev/null +++ b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/clock.c @@ -0,0 +1,10 @@ +/* Copyright 2000 AG Electronics Ltd. */ +/* This code is distributed without warranty under the GPL v2 (see COPYING) */ + +#include <ppc.h> + +unsigned long get_timer_freq(void) +{ + return 100000000 / 4; +} + diff --git a/src/mainboard/motorola/sandpointx3_altimus_mpc7410/flash.h b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/flash.h new file mode 100644 index 0000000000..1d4b812dbc --- /dev/null +++ b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/flash.h @@ -0,0 +1,35 @@ +/* Copyright 2000 AG Electronics Ltd. */ +/* This code is distributed without warranty under the GPL v2 (see COPYING) */ + +#ifndef _FLASH_H +#define _FLASH_H + +struct flash_device; + +typedef struct flash_fn +{ + const char *(* identify)(struct flash_device *flash); + void *(* ptr)(void *data); + int (* erase_all)(void *data); + int (* erase)(void *data, unsigned offset, unsigned length); + int (* program)(void *data, unsigned offset, const void *source, unsigned length); + uint8_t ( *read_byte)(void *data, unsigned offset); +} flash_fn; + +typedef struct flash_device +{ + const flash_fn *fn; + char *tag; + void *data; + unsigned long base; + unsigned size; + unsigned erase_size; + unsigned store_size; + struct flash_device *next; +} flash_device; + +int register_flash_device(const flash_fn *fn, char *tag, void *data); +flash_device *find_flash_device(const char *tag); +int init_flash_amd800(char *tag, unsigned base, unsigned spacing); + +#endif diff --git a/src/mainboard/motorola/sandpointx3_altimus_mpc7410/flash/Config.lb b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/flash/Config.lb new file mode 100644 index 0000000000..d6405314e5 --- /dev/null +++ b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/flash/Config.lb @@ -0,0 +1,2 @@ +object flash.o +object amd800.o diff --git a/src/mainboard/motorola/sandpointx3_altimus_mpc7410/flash/amd800.c b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/flash/amd800.c new file mode 100644 index 0000000000..da56082bfc --- /dev/null +++ b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/flash/amd800.c @@ -0,0 +1,228 @@ +/* Copyright 2000 AG Electronics Ltd. */ +/* This code is distributed without warranty under the GPL v2 (see COPYING) */ + +#include <console/console.h> +#include <stdlib.h> +#include "../flash.h" + +struct data_amd800 +{ + unsigned base; + unsigned spacing; + unsigned cs; + const char *tag; +}; + +static const char *identify_amd (struct flash_device *flash_device); +static int erase_flash_amd800 (void *data, unsigned offset, unsigned length); +static int program_flash_amd800 (void *data, unsigned offset, const void *source, + unsigned length); +static uint8_t read_byte_amd800(void *data, unsigned offset); + +static flash_fn fn_amd800 = { + identify_amd, + 0, + 0, + erase_flash_amd800, + program_flash_amd800, + read_byte_amd800 +}; + +const char *identify_amd (struct flash_device *flash_device) +{ + struct data_amd800 *d800 = flash_device->data; + + if (!d800->tag) + { + volatile unsigned char *flash = + + (volatile unsigned char *) d800->base; + unsigned char type, + id; + + *(flash + 0xaaa * d800->spacing) = 0xaa; + *(flash + 0x555 * d800->spacing) = 0x55; + *(flash + 0xaaa * d800->spacing) = 0x90; + type = *(flash + 2 * d800->spacing); + id = *flash; + *flash = 0xf0; + if ((id == 1 || id == 0x20) && type == 0x5b) + { + d800->cs = 45; + d800->tag = "Am29LV800BB"; + flash_device->base = d800->base; + flash_device->size = 1024*1024; + flash_device->erase_size = 64*1024; + flash_device->store_size = 1; + } + else + { + printk_info("Unknown flash ID: 0x%02x 0x%02x\n", id, type); + } + } + return d800->tag; +} + +int erase_flash_amd800 (void *data, unsigned offset, unsigned length) +{ + struct data_amd800 *d800 = data; + volatile unsigned char *flash = (volatile unsigned char *) d800->base; + volatile unsigned char *flash_aaa = flash + 0xaaa * d800->spacing; + volatile unsigned char *flash_555 = flash + 0x555 * d800->spacing; + int id; + int cs = 9999; + + printk_info("Erase from 0x%08x to 0x%08x\n", offset, offset + length); + *flash_aaa = 0xAA; // Chip Erase + *flash_555 = 0x55; + *flash_aaa = 0x80; + *flash_aaa = 0xAA; + *flash_555 = 0x55; + *flash_aaa = 0x10; + + for (; cs > 0; cs--) + { + id = *(flash + 16); + if (id & 0xA0) // DQ7 or DQ5 set: done or error + break; + printk_info("%4d\b\b\b\b", cs); + } + + *flash_aaa = 0xF0; // In case of error + + printk_info("\b\b\b\b \b\b\b\b"); + if (cs == 0) + { + printk_info("Could not erase flash, timeout.\n"); + return -1; + } + else if ((id & 0x80) == 0) + { + printk_info("Could not erase flash, status=%02x.\n", id); + return -1; + } + printk_info("Flash erased\n"); + return 0; +} + +int init_flash_amd800 (char *tag, unsigned base, unsigned spacing) +{ + struct data_amd800 *data = malloc (sizeof (struct data_amd800)); + + if (data) + { + data->base = base; + data->spacing = spacing; + data->tag = 0; + if (register_flash_device (&fn_amd800, tag, data) < 0) + { + free (data); + return -1; + } + } + else + return -1; + return 0; +} + +int program_flash_amd800 (void *data, unsigned offset, const void *source, + unsigned length) +{ + struct data_amd800 *d800 = data; + volatile unsigned char *flash = (volatile unsigned char *) d800->base; + volatile unsigned char *flash_aaa = flash + 0xaaa * d800->spacing; + volatile unsigned char *flash_555 = flash + 0x555 * d800->spacing; + int id = 0; + int cs; + int errs = 0; + volatile char *s; + volatile char *d; + + printk_info("Program from 0x%08x to 0x%08x\n", offset, offset + length); + printk_info("Data at %p\n", source); + + *flash_aaa = 0xAA; // Unlock Bypass + *flash_555 = 0x55; + *flash_aaa = 0x20; + + s = (unsigned char *) source; + d = flash + offset * d800->spacing; + cs = length; + + while (cs > 0 && !errs) + { + *flash = 0xA0; // Unlock Bypass Program + *d = *s; // Program data + + while (1) + { + id = *d; + if ((id & 0x80) == (*s & 0x80)) // DQ7 right? => program done + break; + else if (id & 0x20) + { // DQ5 set? => maybe errors + id = *d; + if ((id & 0x80) != (*s & 0x80)) + { + errs++; + break; + } + } + } + + // PRINT("Set %08lx = %02x\n", d, *d); + + s += 1; + d += d800->spacing; + cs--; + } + + *flash = 0x90; // Unlock Bypass Program Reset + *flash = 0x00; + *flash = 0xF0; + + if (errs != 0) + { + printk_info("FAIL: Status=%02x Address=%p.\n", id, d - d800->spacing); + return -1; + } + printk_info("OK.\n"); + + + // Step 4: Verify the flash. + + printk_info(" Verifying flash : ..."); + errs = 0; + s = (unsigned char *) source; + d = flash + offset * d800->spacing; + for (cs = 0; cs < length; cs++) + { + if (*s != *d) + { + if (errs == 0) + printk_info("ERROR: Addr: %08p, PCI: %02x Lcl: %02x.\n", + s, *s, *d); + errs++; + } + s += 1; + d += d800->spacing; + } + + if (errs == 0) + printk_info("OK.\n"); + else + { + printk_info(" FAIL: %d errors.\n", errs); + return -1; + } + + return 0; +} + +uint8_t read_byte_amd800 (void *data, unsigned offset) +{ + struct data_amd800 *d800 = data; + volatile unsigned char *flash = (volatile unsigned char *) d800->base; + return *(flash + offset * d800->spacing); +} + diff --git a/src/mainboard/motorola/sandpointx3_altimus_mpc7410/flash/flash.c b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/flash/flash.c new file mode 100644 index 0000000000..3cd50c0827 --- /dev/null +++ b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/flash/flash.c @@ -0,0 +1,46 @@ +/* Copyright 2000 AG Electronics Ltd. */ +/* This code is distributed without warranty under the GPL v2 (see COPYING) */ + +#include <string.h> +#include <console/console.h> +#include <stdlib.h> +#include "../flash.h" + +static flash_device *first_flash = 0; + +int register_flash_device (const flash_fn * fn, char *tag, void *data) +{ + flash_device *device = malloc (sizeof (flash_device)); + + if (device) + { + const char *result; + device->fn = fn; + device->tag = tag; + device->data = data; + if ((result = fn->identify(device)) != 0) + { + printk_info("Registered flash %s\n", result); + device->next = first_flash; + first_flash = device; + } + return result ? 0 : -1; + } + return -1; +} + +flash_device *find_flash_device(const char *name) +{ + int len = strlen(name); + + if (first_flash) + { + flash_device *flash; + + for (flash = first_flash; flash; flash = flash->next) + if (strlen(flash->tag) == len && memcmp(name, flash->tag, len) == 0) + return flash; + } + printk_info ("No flash %s registered\n", name); + return 0; +} diff --git a/src/mainboard/motorola/sandpointx3_altimus_mpc7410/init.c b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/init.c new file mode 100644 index 0000000000..816412b8f7 --- /dev/null +++ b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/init.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2003, Greg Watson <gwatson@lanl.gov> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Do very early board initialization: + * + * - Configure External Bus (EBC) + * - Setup Flash + * - Setup NVRTC + * - Setup Board Control and Status Registers (BCSR) + * - Enable UART0 for debugging + */ + +#include <ppc_asm.tmpl> +#include <ppc.h> +#include <arch/io.h> +#include <printk.h> +#include <uart8250.h> + +void pnp_output(char address, char data) +{ + outb(address, PNP_CFGADDR); + outb(data, PNP_CFGDATA); +} + +void +board_init(void) +{ +} + +void +board_init2(void) +{ + /* + * Enable UART0 + * + * NOTE: this configuration assumes that the PCI/ISA IO + * address space is properly configured by default on board + * reset. While this seems to be the case with the X3, it may not + * always work. + */ + pnp_output(0x07, 6); /* LD 6 = UART0 */ + pnp_output(0x30, 0); /* Dectivate */ + pnp_output(0x60, TTYS0_BASE >> 8); /* IO Base */ + pnp_output(0x61, TTYS0_BASE & 0xFF); /* IO Base */ + pnp_output(0x30, 1); /* Activate */ + uart8250_init(TTYS0_BASE, 115200/TTYS0_BAUD, TTYS0_LCS); + printk_info("Sandpoint initialized...\n"); +} diff --git a/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram.h b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram.h new file mode 100644 index 0000000000..081ffa6758 --- /dev/null +++ b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram.h @@ -0,0 +1,36 @@ +/* Copyright 2000 AG Electronics Ltd. */ +/* This code is distributed without warranty under the GPL v2 (see COPYING) */ +/* Definitions for nvram devices - these are flash or eeprom devices used to + store information across power cycles and resets. Though they are byte + addressable, writes must be committed to allow flash devices to write + complete sectors. */ + +#ifndef _NVRAM_H +#define _NVRAM_H + +typedef struct nvram_device +{ + unsigned (*size)(struct nvram_device *data); + int (*read_block)(struct nvram_device *dev, unsigned offset, + unsigned char *data, unsigned length); + int (*write_byte)(struct nvram_device *dev, unsigned offset, unsigned char byte); + void (*commit)(struct nvram_device *data); + void *data; +} nvram_device; + +int nvram_init (nvram_device *dev); +void nvram_clear(void); + +extern nvram_device pcrtc_nvram; +extern void nvram_putenv(const char *name, const char *value); +extern int nvram_getenv(const char *name, char *buffer, unsigned size); + +typedef const struct nvram_constant +{ + const char *name; + const char *value; +} nvram_constant; + +extern nvram_constant hardcoded_environment[]; + +#endif diff --git a/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram/Config.lb b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram/Config.lb new file mode 100644 index 0000000000..b4ce01bfd0 --- /dev/null +++ b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram/Config.lb @@ -0,0 +1,2 @@ +object bsp_nvram.o +object nvram.o diff --git a/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram/bsp_nvram.c b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram/bsp_nvram.c new file mode 100644 index 0000000000..7208b18d55 --- /dev/null +++ b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram/bsp_nvram.c @@ -0,0 +1,54 @@ +/* + * (C) Copyright 2001 + * Humboldt Solutions Ltd, adrian@humboldt.co.uk. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <arch/io.h> +#include "../nvram.h" + +static unsigned bsp_size(struct nvram_device *data) +{ + return 8 * 1024; +} + +static int bsp_read_block(struct nvram_device *dev, unsigned offset, + unsigned char *data, unsigned length) +{ + unsigned i; + + for(i = 0; i < length; i++) + { + outb(((offset + i) >> 8) & 0xff, 0x74); + outb((offset + i) & 0xff, 0x75); + data[i] = inb(0x76); + } + return length; +} + +static int bsp_write_byte(struct nvram_device *data, unsigned offset, unsigned char byte) +{ + outb((offset >> 8) & 0xff, 0x74); + outb(offset & 0xff, 0x75); + outb(byte, 0x76); + return 1; +} + +nvram_device bsp_nvram = { + bsp_size, bsp_read_block, bsp_write_byte, 0, 0 +}; + diff --git a/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram/nvram.c b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram/nvram.c new file mode 100644 index 0000000000..e6a293b029 --- /dev/null +++ b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram/nvram.c @@ -0,0 +1,101 @@ +/* Copyright 2000 AG Electronics Ltd. */ +/* This code is distributed without warranty under the GPL v2 (see COPYING) */ + +#include <console/console.h> +#include <stdlib.h> +#include "../nvram.h" + +/* NVRAM layout + * + * Environment variable record runs: + * [length]NAME=value[length]NAME=value[0]\0 + * A deleted variable is: + * [length]\0AME=value + * + * When memory is full, we compact. + * + */ +static nvram_device *nvram_dev = 0; +static unsigned char *nvram_buffer = 0; +static unsigned nvram_size = 0; +static uint8_t nvram_csum = 0; +#define NVRAM_INVALID (! nvram_dev) + +static void update_device(unsigned i, unsigned char data) +{ + if (i < nvram_size) + { + nvram_csum -= nvram_buffer[i]; + nvram_buffer[i] = data; + nvram_dev->write_byte(nvram_dev, i, data); + nvram_csum += data; + } + else + printk_info("Offset %d out of range in nvram\n", i); +} + +static void update_csum(void) +{ + nvram_dev->write_byte(nvram_dev, nvram_size, nvram_csum); + if (nvram_dev->commit) + nvram_dev->commit(nvram_dev); +} + +static void update_string_device(unsigned i, const unsigned char *data, + unsigned len) +{ + if (i + len < nvram_size) + { + unsigned j; + for(j = 0; j < len; j++) + { + nvram_csum -= nvram_buffer[i]; + nvram_buffer[i] = *data; + nvram_dev->write_byte(nvram_dev, i, *data); + nvram_csum += *data; + data++; + i++; + } + } + else + printk_info("Offset %d out of range in nvram\n", i + len); +} + +int nvram_init (struct nvram_device *dev) +{ + nvram_dev = dev; + + if (! nvram_size) + nvram_size = dev->size(dev) - 1; + printk_info("NVRAM size is %d\n", nvram_size); + if (!nvram_buffer) + { + unsigned i; + + nvram_buffer = malloc (nvram_size); + if (!nvram_buffer) + return -1; + + nvram_csum = 0; + dev->read_block(dev, 0, nvram_buffer, nvram_size+1); + for(i = 0; i < nvram_size; i++) + nvram_csum += nvram_buffer[i]; + + if (nvram_csum != nvram_buffer[nvram_size]) + { + printk_info("NVRAM checksum invalid - erasing\n"); + //update_device(0, 0); + //update_csum(); + } + } + printk_info("Initialised nvram\n"); + return 0; +} + +void nvram_clear(void) +{ + printk_info("Erasing NVRAM\n"); + update_device(0, 0); + update_csum(); +} + diff --git a/src/mainboard/motorola/sandpointx3_altimus_mpc7410/sp7410.cfg b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/sp7410.cfg new file mode 100644 index 0000000000..b5b8391ec8 --- /dev/null +++ b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/sp7410.cfg @@ -0,0 +1,139 @@ +; bdiGDB configuration file for the Sandpoint X3 evaluation system +; with the Altimus 7410 PMC +;----------------------------------------------------------------- +; +[INIT] +; init core register +WREG MSR 0x00000000 ;clear MSR +; +; init memory controller (based on DINK32) +WM32 0xFEC00000 0x46000080 ;select PCIARB +WM16 0xFEE00002 0x0080 ; +WM32 0xFEC00000 0x73000080 ;select ODCR +WM8 0xFEE00003 0xd1 ; +WM32 0xFEC00000 0x74000080 ;select CDCR +WM16 0xFEE00000 0x00fd ; +WM32 0xFEC00000 0x76000080 ;select MICR +WM8 0xFEE00002 0x40 ; +WM32 0xFEC00000 0x80000080 ;select MSAR1 +WM32 0xFEE00000 0x0080a0c0 ; +WM32 0xFEC00000 0x84000080 ;select MSAR2 +WM32 0xFEE00000 0xe0002040 ; +WM32 0xFEC00000 0x88000080 ;select MSAR3 +WM32 0xFEE00000 0x00000000 ; +WM32 0xFEC00000 0x8c000080 ;select MSAR4 +WM32 0xFEE00000 0x00010101 ; +WM32 0xFEC00000 0x90000080 ;select MEAR1 +WM32 0xFEE00000 0x7f9fbfdf ; +WM32 0xFEC00000 0x94000080 ;select MEAR2 +WM32 0xFEE00000 0xff1f3f5f ; +WM32 0xFEC00000 0x98000080 ;select MEAR3 +WM32 0xFEE00000 0x00000000 ; +WM32 0xFEC00000 0x9c000080 ;select MEAR4 +WM32 0xFEE00000 0x00010101 ; +WM32 0xFEC00000 0xa0000080 ;select MBEN +WM8 0xFEE00000 0x01 ; +WM32 0xFEC00000 0xa3000080 ;select PGMAX +WM8 0xFEE00003 0x32 ; +WM32 0xFEC00000 0xa8000080 ;select PIC1 +WM32 0xFEE00000 0x981a14ff ; +WM32 0xFEC00000 0xac000080 ;select PIC2 +WM32 0xFEE00000 0x00000004 ; +WM32 0xFEC00000 0xe0000080 ;select AMBOR +WM8 0xFEE00000 0xc0 ; +WM32 0xFEC00000 0xf0000080 ;select MCCR1 +WM32 0xFEE00000 0xaaaae075 ;do not set MEMGO +WM32 0xFEC00000 0xf4000080 ;select MCCR2 +WM32 0xFEE00000 0x2c184004 ; +WM32 0xFEC00000 0xf8000080 ;select MCCR3 +WM32 0xFEE00000 0x00003078 ; +WM32 0xFEC00000 0xfc000080 ;select MCCR4 +WM32 0xFEE00000 0x39223235 ; +DELAY 100 +WM32 0xFEC00000 0xf0000080 ;select MCCR1 +WM32 0xFEE00000 0xaaaae875 ;now set MEMGO +; +WM32 0xFEC00000 0x78000080 ;select EUMBBAR +WM32 0xFEE00000 0x000000fc ;Embedded utility memory block at 0xFC000000 +; +;WM32 0xFEC00000 0xa8000080 ;select PICR1 +;WM32 0xFEE00000 0x901014ff ;enable flash write (Flash on processor bus) + +; +; Enable UART0 +; +WM8 0xFE00015C 0x07 +WM8 0xFE00015D 0x06 +WM8 0xFE00015C 0x30 +WM8 0xFE00015D 0x00 +WM8 0xFE00015C 0x60 +WM8 0xFE00015D 0x03 +WM8 0xFE00015C 0x61 +WM8 0xFE00015D 0xf8 +WM8 0xFE00015C 0x30 +WM8 0xFE00015D 0x01 +; +; define maximal transfer size +;TSZ1 0xFF800000 0xFFFFFFFF ;ROM space (only for PCI boot ROM) +TSZ4 0xFF800000 0xFFFFFFFF ;ROM space (only for Local bus flash) + + +[TARGET] +CPUTYPE 7400 ;the CPU type (603EV,750,8240,8260,7400) +JTAGCLOCK 0 ;use 16 MHz JTAG clock +WORKSPACE 0x00000000 ;workspace in target RAM for data cache flush +BDIMODE AGENT ;the BDI working mode (LOADONLY | AGENT | GATEWAY) +BREAKMODE HARD ;SOFT or HARD, HARD uses PPC hardware breakpoint +;STEPMODE HWBP ;TRACE or HWBP, HWPB uses a hardware breakpoint +;VECTOR CATCH ;catch unhandled exceptions +DCACHE NOFLUSH ;data cache flushing (FLUSH | NOFLUSH) +;PARITY ON ;enable data parity generation +MEMDELAY 400 ;additional memory access delay +;REGLIST STD ;select register to transfer to GDB +;L2PM 0x00100000 0x80000 ;L2 privat memory +;SIO 2002 115200 +SIO 2002 9600 +;MMU XLAT +;PTBASE 0x000000f0 + +[HOST] +IP 10.0.1.11 +;FILE E:\cygnus\root\usr\demo\sp7400\vxworks +FILE linuxbios.elf +FORMAT ELF +;START 0x403104 +LOAD MANUAL ;load code MANUAL or AUTO after reset +DEBUGPORT 2001 + +[FLASH] +; Am29LV800BB on local processor bus (RCS0) +; set PPMC7410 switch SW2-1 OFF => ROM on Local bus +; enable flash write in PICR1 (see INIT part) +; set maximal transfer size to 4 bytes (see INIT part) +CHIPTYPE AM29BX8 ;Flash type (AM29F | AM29BX8 | AM29BX16 | I28BX8 | I28BX16) +CHIPSIZE 0x100000 ;The size of one flash chip in bytes (e.g. Am29LV800BB = 0x100000) +BUSWIDTH 8 ;The width of the flash memory bus in bits (8 | 16 | 32 | 64) +WORKSPACE 0x00000000 ;workspace in SDRAM +FILE linuxbios.elf +FORMAT ELF +ERASE 0xFFF00000 ;erase sector 0 of flash +ERASE 0xFFF04000 ;erase sector 1 of flash +ERASE 0xFFF06000 ;erase sector 2 of flash +ERASE 0xFFF08000 ;erase sector 3 of flash +ERASE 0xFFF10000 ;erase sector 4 of flash +ERASE 0xFFF20000 ;erase sector 5 of flash +ERASE 0xFFF30000 ;erase sector 6 of flash +ERASE 0xFFF40000 ;erase sector 7 of flash +ERASE 0xFFF50000 ;erase sector 8 of flash +ERASE 0xFFF60000 ;erase sector 9 of flash +ERASE 0xFFF70000 ;erase sector 10 of flash + +[REGS] +DMM1 0xFC000000 ;Embedded utility memory base address +IMM1 0xFEC00000 0xFEE00000 ;configuration registers at byte offset 0 +IMM2 0xFEC00000 0xFEE00001 ;configuration registers at byte offset 1 +IMM3 0xFEC00000 0xFEE00002 ;configuration registers at byte offset 2 +IMM4 0xFEC00000 0xFEE00003 ;configuration registers at byte offset 3 +FILE mpc107.def + + diff --git a/src/mainboard/totalimpact/briq/Config.lb b/src/mainboard/totalimpact/briq/Config.lb index 775aad36f8..ba91f2dfcb 100644 --- a/src/mainboard/totalimpact/briq/Config.lb +++ b/src/mainboard/totalimpact/briq/Config.lb @@ -16,17 +16,31 @@ object clock.o arch ppc end if CONFIG_BRIQ_750FX - chip cpu/ppc/ppc7xx device pnp 0.0 on end end +dir /cpu/ppc/ppc7xx end if CONFIG_BRIQ_7400 - chip cpu/ppc/mpc74xx device pnp 0.0 on end end +dir /cpu/ppc/mpc74xx end ## ## Include the secondary Configuration files ## -chip northbridge/ibm/cpc710 device pnp 0.0 on end end -chip southbridge/winbond/w83c553 device pnp 0.0 on end end +chip northbridge/ibm/cpc710 + device pci_domain 0 on # 32bit pci bridge + device pci 0.0 on + chip southbridge/winbond/w83c553 + # FIXME The function numbers are ok but the device id is wrong here! + device pci 0.0 on end # pci to isa bridge + device pci 0.1 on end # pci ide controller + end + end + end + device cpu_bus 0 on + # chip cpu/ppc/ppc7xx + # device cpu 0 on end + # end + end +end ## ## Build the objects we have code for in this directory. diff --git a/src/northbridge/amd/amdk8/northbridge.c b/src/northbridge/amd/amdk8/northbridge.c index 85f8fe4e86..464e66c51f 100644 --- a/src/northbridge/amd/amdk8/northbridge.c +++ b/src/northbridge/amd/amdk8/northbridge.c @@ -657,6 +657,7 @@ static struct device_operations pci_domain_ops = { .enable_resources = enable_childrens_resources, .init = 0, .scan_bus = pci_domain_scan_bus, + .ops_pci_bus = &pci_cf8_conf1, }; static unsigned int cpu_bus_scan(device_t dev, unsigned int max) @@ -726,7 +727,6 @@ static void root_complex_enable_dev(struct device *dev) /* Set the operations if it is a special bus type */ if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { dev->ops = &pci_domain_ops; - pci_set_method_conf1(); } else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { dev->ops = &cpu_bus_ops; diff --git a/src/northbridge/emulation/qemu-i386/northbridge.c b/src/northbridge/emulation/qemu-i386/northbridge.c index 0a8ed5c1d8..dd120e29a5 100644 --- a/src/northbridge/emulation/qemu-i386/northbridge.c +++ b/src/northbridge/emulation/qemu-i386/northbridge.c @@ -115,7 +115,7 @@ static void enable_dev(struct device *dev) /* Set the operations if it is a special bus type */ if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { dev->ops = &pci_domain_ops; - pci_set_method(); + pci_set_method(dev); } } diff --git a/src/northbridge/ibm/cpc710/Config.lb b/src/northbridge/ibm/cpc710/Config.lb index 8d8a895bd7..054a4c3997 100644 --- a/src/northbridge/ibm/cpc710/Config.lb +++ b/src/northbridge/ibm/cpc710/Config.lb @@ -2,10 +2,13 @@ # Config file for IBM CPC710 # +config chip.h + initobject cpc710.o initobject cpc710_pci.o #initobject cpc710_sdram.o object cpc710.o object cpc710_pci.o -object cpc710_sdram.o +#object cpc710_sdram.o +driver cpc710_northbridge.o diff --git a/src/northbridge/ibm/cpc710/chip.h b/src/northbridge/ibm/cpc710/chip.h new file mode 100644 index 0000000000..e2b2ed5eaa --- /dev/null +++ b/src/northbridge/ibm/cpc710/chip.h @@ -0,0 +1,6 @@ + +struct northbridge_ibm_cpc710_config { + /* Nothing yet */ +}; + +extern struct chip_operations northbridge_ibm_cpc710_ops; diff --git a/src/northbridge/ibm/cpc710/cpc710_northbridge.c b/src/northbridge/ibm/cpc710/cpc710_northbridge.c new file mode 100644 index 0000000000..2633dcd02c --- /dev/null +++ b/src/northbridge/ibm/cpc710/cpc710_northbridge.c @@ -0,0 +1,103 @@ +#include <console/console.h> +#include <arch/io.h> +#include <stdint.h> +#include <device/device.h> +#include <device/pci.h> +#include <stdlib.h> +#include <string.h> +#include <bitops.h> +#include <cpu/cpu.h> +#include "chip.h" + +static void pci_domain_read_resources(device_t dev) +{ + struct resource *resource; + + /* Initialize the system wide io space constraints */ + resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0)); + resource->base = 0; + resource->limit = 0xffffUL; + resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + + /* Initialize the system wide memory resources constraints */ + resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0)); + resource->base = 0x80000000ULL; + resource->limit = 0xfeffffffULL; /* We can put pci resources in the system controll area */ + resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; +} + +static void ram_resource(device_t dev, unsigned long index, + unsigned long basek, unsigned long sizek) +{ + struct resource *resource; + + if (!sizek) { + return; + } + resource = new_resource(dev, index); + resource->base = ((resource_t)basek) << 10; + resource->size = ((resource_t)sizek) << 10; + resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \ + IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; +} + +static void pci_domain_set_resources(device_t dev) +{ + int idx; + + /* Report the memory regions */ + idx = 10; + ram_resource(dev, idx++, 0, 1024*1024); /* FIXME */ + + /* And assign the resources */ + assign_resources(&dev->link[0]); +} + + +static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max) +{ + max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max); + return max; +} + +static struct device_operations pci_domain_ops = { + .read_resources = pci_domain_read_resources, + .set_resources = pci_domain_set_resources, + .enable_resources = enable_childrens_resources, + .init = 0, + .scan_bus = pci_domain_scan_bus, + .ops_pci_bus = &pci_ppc_conf1, +}; + +static void cpu_bus_init(device_t dev) +{ + initialize_cpus(&dev->link[0]); +} + +static void cpu_bus_noop(device_t dev) +{ +} + +static struct device_operations cpu_bus_ops = { + .read_resources = cpu_bus_noop, + .set_resources = cpu_bus_noop, + .enable_resources = cpu_bus_noop, + .init = cpu_bus_init, + .scan_bus = 0, +}; + +static void enable_dev(struct device *dev) +{ + /* Set the operations if it is a special bus type */ + if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { + dev->ops = &pci_domain_ops; + } + else if (dev->path.type == DEVICE_PATH_CPU_BUS) { + dev->ops = &cpu_bus_ops; + } +} + +struct chip_operations northbridge_ibm_cpc710_ops = { + CHIP_NAME("CPC710") + .enable_dev = enable_dev, +}; diff --git a/src/northbridge/intel/e7501/northbridge.c b/src/northbridge/intel/e7501/northbridge.c index 6140c3f051..800831de3e 100644 --- a/src/northbridge/intel/e7501/northbridge.c +++ b/src/northbridge/intel/e7501/northbridge.c @@ -8,8 +8,6 @@ #include <bitops.h> #include "chip.h" -#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM) - static void pci_domain_read_resources(device_t dev) { struct resource *resource; @@ -67,7 +65,6 @@ static uint32_t find_pci_tolm(struct bus *bus) static void pci_domain_set_resources(device_t dev) { - struct resource *resource, *last; device_t mc_dev; uint32_t pci_tolm; @@ -157,6 +154,7 @@ static struct device_operations pci_domain_ops = { .enable_resources = enable_childrens_resources, .init = 0, .scan_bus = pci_domain_scan_bus, + .ops_pci_bus = &pci_cf8_conf1, }; static void cpu_bus_init(device_t dev) @@ -181,7 +179,6 @@ static void enable_dev(struct device *dev) /* Set the operations if it is a special bus type */ if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { dev->ops = &pci_domain_ops; - pci_set_method_conf1(); } else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { dev->ops = &cpu_bus_ops; diff --git a/src/northbridge/intel/i855pm/northbridge.c b/src/northbridge/intel/i855pm/northbridge.c index c311a05edc..e612cf1efc 100644 --- a/src/northbridge/intel/i855pm/northbridge.c +++ b/src/northbridge/intel/i855pm/northbridge.c @@ -149,7 +149,7 @@ static void enable_dev(struct device *dev) /* Set the operations if it is a special bus type */ if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { dev->ops = &pci_domain_ops; - pci_set_method(); + pci_set_method(dev); } else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { dev->ops = &cpu_bus_ops; diff --git a/src/northbridge/motorola/mpc107/Config.lb b/src/northbridge/motorola/mpc107/Config.lb index c5eb4256ac..78fc99e85f 100644 --- a/src/northbridge/motorola/mpc107/Config.lb +++ b/src/northbridge/motorola/mpc107/Config.lb @@ -2,10 +2,9 @@ # Objects linked with linuxbios # +config chip.h # We need sdram_init() in ppc_main() initobject meminfo.o initobject mpc107.o -# We need sizeram() in hardwaremain() -object meminfo.o -object mpc107.o +object mpc107_northbridge.c diff --git a/src/northbridge/motorola/mpc107/mpc107.c b/src/northbridge/motorola/mpc107/mpc107.c index e7e75b9af5..ec91a675d7 100644 --- a/src/northbridge/motorola/mpc107/mpc107.c +++ b/src/northbridge/motorola/mpc107/mpc107.c @@ -25,7 +25,6 @@ #include <arch/pciconf.h> #include <timer.h> #include <clock.h> -#include <mem.h> #include "i2c.h" #include "mpc107.h" @@ -45,27 +44,6 @@ memory_init(void) (void)mpc107_config_memory(NUM_BANKS, banks, 2); } -struct mem_range * -sizeram(void) -{ - int i; - struct sdram_dimm_info dimms[NUM_DIMMS]; - struct sdram_bank_info banks[NUM_BANKS]; - static struct mem_range meminfo; - - meminfo.basek = 0; - meminfo.sizek = 0; - - mpc107_probe_dimms(NUM_DIMMS, dimms, banks); - - for (i = 0; i < NUM_BANKS; i++) - meminfo.sizek += banks[i].size; - - meminfo.sizek >>= 10; - - return &meminfo; -} - /* * Configure the MPC107 with the most pessimistic settings. These * are modified by reading the SPD EEPROM and adjusting accordingly. diff --git a/src/northbridge/transmeta/tm5800/northbridge.c b/src/northbridge/transmeta/tm5800/northbridge.c index 8a85a9e704..5ee97393e9 100644 --- a/src/northbridge/transmeta/tm5800/northbridge.c +++ b/src/northbridge/transmeta/tm5800/northbridge.c @@ -142,7 +142,7 @@ static void enable_dev(struct device *dev) /* Set the operations if it is a special bus type */ if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { dev->ops = &pci_domain_ops; - pci_set_method(); + pci_set_method(dev); } else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { dev->ops = &cpu_bus_ops; diff --git a/src/northbridge/via/vt8601/northbridge.c b/src/northbridge/via/vt8601/northbridge.c index 4daedc5f3e..b578a975e4 100644 --- a/src/northbridge/via/vt8601/northbridge.c +++ b/src/northbridge/via/vt8601/northbridge.c @@ -186,7 +186,7 @@ static void enable_dev(struct device *dev) /* Set the operations if it is a special bus type */ if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { dev->ops = &pci_domain_ops; - pci_set_method(); + pci_set_method(dev); } else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { dev->ops = &cpu_bus_ops; diff --git a/src/northbridge/via/vt8623/northbridge.c b/src/northbridge/via/vt8623/northbridge.c index 94880b9102..77c03d0bc8 100644 --- a/src/northbridge/via/vt8623/northbridge.c +++ b/src/northbridge/via/vt8623/northbridge.c @@ -268,7 +268,7 @@ static void enable_dev(struct device *dev) /* Set the operations if it is a special bus type */ if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { dev->ops = &pci_domain_ops; - pci_set_method(); + pci_set_method(dev); } else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { dev->ops = &cpu_bus_ops; diff --git a/src/pc80/keyboard.c b/src/pc80/keyboard.c index f46d1ffa16..ccec00488c 100644 --- a/src/pc80/keyboard.c +++ b/src/pc80/keyboard.c @@ -26,7 +26,6 @@ static int kbd_empty_output_buffer(void) static void pc_keyboard_init(struct pc_keyboard *keyboard) { unsigned char regval; - unsigned long timeout; /* send cmd = 0xAA, self test 8042 */ outb(0xaa, 0x64); diff --git a/src/pmc/altimus/mpc7410/Config.lb b/src/pmc/altimus/mpc7410/Config.lb index 29dc45ed08..c162aa15ba 100644 --- a/src/pmc/altimus/mpc7410/Config.lb +++ b/src/pmc/altimus/mpc7410/Config.lb @@ -1,12 +1,12 @@ ## ## CPU initialization ## -chip cpu/ppc/mpc74xx device pnp 0.0 on end end +dir /cpu/ppc/mpc74xx ## ## Include the secondary Configuration files ## -chip northbridge/motorola/mpc107 device pnp 0.0 on end end +dir /northbridge/motrola/mpc107 ## ## Build the objects we have code for in this directory. diff --git a/src/superio/NSC/pc97307/superio.c b/src/superio/NSC/pc97307/superio.c index ebe5d36ee2..711b98639f 100644 --- a/src/superio/NSC/pc97307/superio.c +++ b/src/superio/NSC/pc97307/superio.c @@ -3,6 +3,8 @@ #include <arch/io.h> #include <console/console.h> +#include <device/device.h> +#include <device/pnp.h> #include "chip.h" #include "pc97307.h" @@ -14,7 +16,7 @@ static void init(device_t dev) if (!dev->enabled) { return; } - conf = dev->chip; + conf = dev->chip_info; switch(dev->path.u.pnp.device) { case PC97307_SP1: res0 = find_resource(dev, PNP_IDX_IO0); @@ -39,6 +41,8 @@ static void init(device_t dev) break; case PC97307_FDC: + { + unsigned reg; /* Set up floppy in PS/2 mode */ outb(0x09, SIO_CONFIG_RA); reg = inb(SIO_CONFIG_RD); @@ -46,7 +50,9 @@ static void init(device_t dev) outb(reg, SIO_CONFIG_RD); outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */ break; - + } + default: + break; } } @@ -76,7 +82,7 @@ static void enable_dev(struct device *dev) sizeof(pnp_dev_info)/sizeof(pnp_dev_info[0]), pnp_dev_info); } -struct chip_operations superio_NSC_pc97307_control = { +struct chip_operations superio_NSC_pc97307_ops = { CHIP_NAME("NSC 97307") .enable_dev = enable_dev, }; |