- 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
This commit is contained in:
Eric Biederman 2004-11-18 22:38:08 +00:00
parent bec8acedf1
commit a9e632c2ac
62 changed files with 1467 additions and 322 deletions

View File

@ -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) static struct lb_memory *build_lb_mem(struct lb_header *head)
{ {
struct lb_memory *mem; struct lb_memory *mem;
struct device *dev;
/* Record where the lb memory ranges will live */ /* Record where the lb memory ranges will live */
mem = lb_memory(head); mem = lb_memory(head);
@ -343,7 +342,7 @@ unsigned long write_linuxbios_table(
struct lb_record *rec_dest, *rec_src; struct lb_record *rec_dest, *rec_src;
/* Write the option config table... */ /* Write the option config table... */
rec_dest = lb_new_record(head); 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); memcpy(rec_dest, rec_src, rec_src->size);
} }
/* Record where RAM is located */ /* Record where RAM is located */

View File

@ -1,18 +1,9 @@
#ifndef ARCH_I386_PCI_OPS_H #ifndef ARCH_I386_PCI_OPS_H
#define ARCH_I386_PCI_OPS_H #define ARCH_I386_PCI_OPS_H
struct pci_ops { const struct pci_bus_operations pci_cf8_conf1;
uint8_t (*read8) (uint8_t bus, int devfn, int where); const struct pci_bus_operations pci_cf8_conf2;
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;
void pci_set_method_conf1(void); void pci_set_method(device_t dev);
void pci_set_method_conf2(void);
void pci_set_method(void);
#endif /* ARCH_I386_PCI_OPS_H */ #endif /* ARCH_I386_PCI_OPS_H */

View File

@ -6,7 +6,7 @@
#option CONFIG_PCIBIOS_IRQ=0 #option CONFIG_PCIBIOS_IRQ=0
object c_start.S object c_start.S
object cpu.c object cpu.c
object pci_ops.c #object pci_ops.c
object pci_ops_conf1.c object pci_ops_conf1.c
object pci_ops_conf2.c object pci_ops_conf2.c
object pci_ops_auto.c object pci_ops_auto.c

View File

@ -420,7 +420,7 @@ void x86_exception(struct eregs *info)
if ( parse_ulong(&ptr, &addr) && if ( parse_ulong(&ptr, &addr) &&
(*ptr++ == ',') && (*ptr++ == ',') &&
parse_ulong(&ptr, &length)) { parse_ulong(&ptr, &length)) {
copy_to_hex(out_buffer, addr, length); copy_to_hex(out_buffer, (void *)addr, length);
} else { } else {
memcpy(out_buffer, "E01", 4); memcpy(out_buffer, "E01", 4);
} }

View File

@ -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);
}

View File

@ -1,3 +1,4 @@
#include <stddef.h>
#include <console/console.h> #include <console/console.h>
#include <arch/io.h> #include <arch/io.h>
#include <arch/pciconf.h> #include <arch/pciconf.h>
@ -15,11 +16,12 @@
* This should be close to trivial, but it isn't, because there are buggy * 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. * 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; uint16_t class, vendor;
uint8_t bus; unsigned bus;
int devfn; int devfn;
struct bus pbus; /* Dummy device */
#define PCI_CLASS_BRIDGE_HOST 0x0600 #define PCI_CLASS_BRIDGE_HOST 0x0600
#define PCI_CLASS_DISPLAY_VGA 0x0300 #define PCI_CLASS_DISPLAY_VGA 0x0300
#define PCI_VENDOR_ID_COMPAQ 0x0e11 #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 #define PCI_VENDOR_ID_MOTOROLA 0x1057
for (bus = 0, devfn = 0; devfn < 0x100; devfn++) { for (bus = 0, devfn = 0; devfn < 0x100; devfn++) {
class = o->read16(bus, devfn, PCI_CLASS_DEVICE); class = o->read16(&pbus, bus, devfn, PCI_CLASS_DEVICE);
vendor = o->read16(bus, devfn, PCI_VENDOR_ID); vendor = o->read16(&pbus, bus, devfn, PCI_VENDOR_ID);
if (((class == PCI_CLASS_BRIDGE_HOST) || (class == PCI_CLASS_DISPLAY_VGA)) || 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_INTEL) || (vendor == PCI_VENDOR_ID_COMPAQ) ||
(vendor == PCI_VENDOR_ID_MOTOROLA))) { (vendor == PCI_VENDOR_ID_MOTOROLA))) {
@ -39,7 +41,7 @@ static int pci_sanity_check(const struct pci_ops *o)
return 0; return 0;
} }
static void pci_check_direct(void) const struct pci_bus_operations *pci_check_direct(void)
{ {
unsigned int tmp; unsigned int tmp;
@ -50,13 +52,12 @@ static void pci_check_direct(void)
outb(0x01, 0xCFB); outb(0x01, 0xCFB);
tmp = inl(0xCF8); tmp = inl(0xCF8);
outl(0x80000000, 0xCF8); outl(0x80000000, 0xCF8);
if (inl(0xCF8) == 0x80000000) { if ((inl(0xCF8) == 0x80000000) &&
pci_set_method_conf1(); pci_sanity_check(&pci_cf8_conf1))
if (pci_sanity_check(conf)) { {
outl(tmp, 0xCF8); outl(tmp, 0xCF8);
printk_debug("PCI: Using configuration type 1\n"); printk_debug("PCI: Using configuration type 1\n");
return; return &pci_cf8_conf1;
}
} }
outl(tmp, 0xCF8); outl(tmp, 0xCF8);
} }
@ -68,25 +69,23 @@ static void pci_check_direct(void)
outb(0x00, 0xCFB); outb(0x00, 0xCFB);
outb(0x00, 0xCF8); outb(0x00, 0xCF8);
outb(0x00, 0xCFA); outb(0x00, 0xCFA);
if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00) { if ((inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00) &&
pci_set_method_conf2(); pci_sanity_check(&pci_cf8_conf2))
if (pci_sanity_check(conf)) { {
printk_debug("PCI: Using configuration type 2\n"); printk_debug("PCI: Using configuration type 2\n");
} return &pci_cf8_conf2;
} }
} }
printk_debug("pci_check_direct failed\n"); die("pci_check_direct failed\n");
conf = 0; return NULL;
return;
} }
/** Set the method to be used for PCI, type I or type II /** 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"); printk_info("Finding PCI configuration type.\n");
pci_check_direct(); dev->ops->ops_pci_bus = pci_check_direct();
post_code(0x5f); post_code(0x5f);
} }

View File

@ -10,37 +10,37 @@
#define CONFIG_CMD(bus,devfn, where) (0x80000000 | (bus << 16) | (devfn << 8) | (where & ~3)) #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); outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
return inb(0xCFC + (where & 3)); 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); outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
return inw(0xCFC + (where & 2)); 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); outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
return inl(0xCFC); 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); outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
outb(value, 0xCFC + (where & 3)); 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); outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
outw(value, 0xCFC + (where & 2)); 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(CONFIG_CMD(bus, devfn, where), 0xCF8);
outl(value, 0xCFC); outl(value, 0xCFC);
@ -48,7 +48,7 @@ static void pci_conf1_write_config32(unsigned char bus, int devfn, int where, ui
#undef CONFIG_CMD #undef CONFIG_CMD
static const struct pci_ops pci_direct_conf1 = const struct pci_bus_operations pci_cf8_conf1 =
{ {
.read8 = pci_conf1_read_config8, .read8 = pci_conf1_read_config8,
.read16 = pci_conf1_read_config16, .read16 = pci_conf1_read_config16,
@ -57,8 +57,3 @@ static const struct pci_ops pci_direct_conf1 =
.write16 = pci_conf1_write_config16, .write16 = pci_conf1_write_config16,
.write32 = pci_conf1_write_config32, .write32 = pci_conf1_write_config32,
}; };
void pci_set_method_conf1(void)
{
conf = &pci_direct_conf1;
}

View File

@ -12,7 +12,7 @@
#define FUNC(devfn) (((devfn & 7) << 1) | 0xf0) #define FUNC(devfn) (((devfn & 7) << 1) | 0xf0)
#define SET(bus,devfn) outb(FUNC(devfn), 0xCF8); outb(bus, 0xCFA); #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; uint8_t value;
SET(bus, devfn); SET(bus, devfn);
@ -21,7 +21,7 @@ static uint8_t pci_conf2_read_config8(unsigned char bus, int devfn, int where)
return value; 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; uint16_t value;
SET(bus, devfn); SET(bus, devfn);
@ -30,7 +30,7 @@ static uint16_t pci_conf2_read_config16(unsigned char bus, int devfn, int where)
return value; 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; uint32_t value;
SET(bus, devfn); SET(bus, devfn);
@ -39,21 +39,21 @@ static uint32_t pci_conf2_read_config32(unsigned char bus, int devfn, int where)
return value; 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); SET(bus, devfn);
outb(value, IOADDR(devfn, where)); outb(value, IOADDR(devfn, where));
outb(0, 0xCF8); 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); SET(bus, devfn);
outw(value, IOADDR(devfn, where)); outw(value, IOADDR(devfn, where));
outb(0, 0xCF8); 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); SET(bus, devfn);
outl(value, IOADDR(devfn, where)); 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 IOADDR
#undef FUNC #undef FUNC
static const struct pci_ops pci_direct_conf2 = const struct pci_bus_operations pci_cf8_conf2 =
{ {
.read8 = pci_conf2_read_config8, .read8 = pci_conf2_read_config8,
.read16 = pci_conf2_read_config16, .read16 = pci_conf2_read_config16,
@ -74,7 +74,3 @@ static const struct pci_ops pci_direct_conf2 =
.write32 = pci_conf2_write_config32, .write32 = pci_conf2_write_config32,
}; };
void pci_set_method_conf2(void)
{
conf = &pci_direct_conf2;
}

View File

@ -1,3 +1,60 @@
#ifndef ARCH_CPU_H
#define ARCH_CPU_H
/* /*
* this should probably integrate code from src/arch/ppc/lib/cpuid.c * 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 */

View File

@ -1,6 +1,6 @@
#ifndef ARCH_I386_PCI_OPS_H #ifndef ARCH_PPC_PCI_OPS_H
#define ARCH_I386_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 */

View File

@ -1,15 +1,17 @@
object c_start.S object c_start.S
object setup.o object setup.o
object pci_ops.o object pci_ppc_conf1_ops.o
object pci_dev.o object pci_dev.o
object timer.o object timer.o
object cpuid.o object cpuid.o
object cpu.o object cpu.o
object timebase.S object timebase.S
object floats.S object floats.S
object div64.S
initobject pci_dev.o initobject pci_dev.o
initobject printk_init.o initobject printk_init.o
initobject timebase.S initobject timebase.S
initobject timer.o initobject timer.o
initobject setup.o initobject setup.o
initobject floats.S initobject floats.S
initobject div64.S

View File

@ -17,6 +17,8 @@
_start: _start:
/* /*
* init stack pointer to real ram now that memory is on * 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 li r0, 0
lis r1, _estack@ha lis r1, _estack@ha

View File

@ -1,12 +1,32 @@
#include <console/console.h> #include <console/console.h>
#include <arch/io.h> #include <arch/io.h>
#include <string.h> #include <string.h>
#include <device/device.h>
#include <cpu/cpu.h> #include <cpu/cpu.h>
#include <cpu/ppc/cpuid.h> #include <cpu/ppc/cpuid.h>
#include "ppc.h" #include "ppc.h"
#include "ppcreg.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) void cpu_initialize(void)
{ {
@ -27,7 +47,7 @@ void cpu_initialize(void)
} }
/* Find what type of cpu we are dealing with */ /* 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(); cpu->device = ppc_getpvr();
display_cpuid(cpu); display_cpuid(cpu);
@ -44,7 +64,6 @@ void cpu_initialize(void)
#endif #endif
/* Turn on caching if we haven't already */ /* Turn on caching if we haven't already */
printk_info("CPU #%d Initialized\n", processor_id); printk_info("CPU #%d Initialized\n", info->index);
return processor_id; return;
} }

58
src/arch/ppc/lib/div64.S Normal file
View File

@ -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

View File

@ -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
};

View File

@ -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,
};

View File

@ -19,3 +19,5 @@ initinclude "FAMILY_INIT" cpu/ppc/mpc74xx/mpc74xx.inc
object cache.S object cache.S
initobject cache.S initobject cache.S
dir /cpu/simple_init

View File

@ -24,3 +24,4 @@ object mem.o
object clock.o object clock.o
object cache.S object cache.S
dir /cpu/simple_init

View File

@ -21,3 +21,5 @@ object clock.o
object cache.S object cache.S
initobject clock.o initobject clock.o
initobject cache.S initobject cache.S
dir /cpu/simple_init

View File

@ -1,7 +1,7 @@
#include <linux/console.h> #include <console/console.h>
#include <device/device.h> #include <device/device.h>
#include <device/path.h> #include <device/path.h>
#include <device/cpu.h> #include <cpu/cpu.h>
#if CONFIG_SMP #if CONFIG_SMP
#error "This Configuration does not support SMP" #error "This Configuration does not support SMP"
@ -16,10 +16,11 @@ void initialize_cpus(struct bus *cpu_bus)
info = cpu_info(); info = cpu_info();
/* Get the device path of the boot cpu */ /* 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 */ /* 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 */ /* Initialize the bootstrap processor */
cpu_initialize(); cpu_initialize();

View File

@ -301,7 +301,8 @@ void initialize_cpus(struct bus *cpu_bus)
cpu_path.u.apic.apic_id = lapicid(); cpu_path.u.apic.apic_id = lapicid();
#else #else
/* Get the device path of the boot cpu */ /* 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 #endif
/* Find the device structure for the boot cpu */ /* Find the device structure for the boot cpu */

View File

@ -4,3 +4,4 @@ object device_util.o
object pci_device.o object pci_device.o
object pnp_device.o object pnp_device.o
object hypertransport.o object hypertransport.o
object pci_ops.o

View File

@ -114,9 +114,6 @@ const char *dev_path(device_t dev)
case DEVICE_PATH_ROOT: case DEVICE_PATH_ROOT:
memcpy(buffer, "Root Device", 12); memcpy(buffer, "Root Device", 12);
break; break;
case DEVICE_PATH_DEFAULT_CPU:
memcpy(buffer, "Default CPU", 12);
break;
case DEVICE_PATH_PCI: case DEVICE_PATH_PCI:
sprintf(buffer, "PCI: %02x:%02x.%01x", sprintf(buffer, "PCI: %02x:%02x.%01x",
dev->bus->secondary, dev->bus->secondary,
@ -142,6 +139,12 @@ const char *dev_path(device_t dev)
sprintf(buffer, "APIC_CLUSTER: %01x", sprintf(buffer, "APIC_CLUSTER: %01x",
dev->path.u.apic_cluster.cluster); dev->path.u.apic_cluster.cluster);
break; 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: default:
printk_err("Unknown device path type: %d\n", dev->path.type); printk_err("Unknown device path type: %d\n", dev->path.type);
break; break;
@ -160,9 +163,6 @@ int path_eq(struct device_path *path1, struct device_path *path2)
case DEVICE_PATH_ROOT: case DEVICE_PATH_ROOT:
equal = 1; equal = 1;
break; break;
case DEVICE_PATH_DEFAULT_CPU:
equal = 1;
break;
case DEVICE_PATH_PCI: case DEVICE_PATH_PCI:
equal = (path1->u.pci.devfn == path2->u.pci.devfn); equal = (path1->u.pci.devfn == path2->u.pci.devfn);
break; break;
@ -182,6 +182,12 @@ int path_eq(struct device_path *path1, struct device_path *path2)
case DEVICE_PATH_APIC_CLUSTER: case DEVICE_PATH_APIC_CLUSTER:
equal = (path1->u.apic_cluster.cluster == path2->u.apic_cluster.cluster); equal = (path1->u.apic_cluster.cluster == path2->u.apic_cluster.cluster);
break; 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: default:
printk_err("Uknown device type: %d\n", path1->type); printk_err("Uknown device type: %d\n", path1->type);
break; break;

View File

@ -480,7 +480,7 @@ void pci_dev_set_resources(struct device *dev)
void pci_dev_enable_resources(struct device *dev) void pci_dev_enable_resources(struct device *dev)
{ {
struct pci_operations *ops; const struct pci_operations *ops;
uint16_t command; uint16_t command;
/* Set the subsystem vendor and device id for mainboard devices */ /* 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); enable_childrens_resources(dev);
} }
void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device) void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{ {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 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 */ /** 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, .set_subsystem = pci_dev_set_subsystem,
}; };
@ -533,11 +534,11 @@ struct device_operations default_pci_ops_dev = {
.init = 0, .init = 0,
.scan_bus = 0, .scan_bus = 0,
.enable = 0, .enable = 0,
.ops_pci = &pci_ops_pci_dev, .ops_pci = &pci_dev_ops_pci,
}; };
/** Default device operations for PCI bridges */ /** 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, .set_subsystem = 0,
}; };
struct device_operations default_pci_ops_bus = { struct device_operations default_pci_ops_bus = {
@ -547,7 +548,7 @@ struct device_operations default_pci_ops_bus = {
.init = 0, .init = 0,
.scan_bus = pci_scan_bridge, .scan_bus = pci_scan_bridge,
.enable = 0, .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; uint16_t cr;
bus = &dev->link[0]; bus = &dev->link[0];
bus->dev = dev;
dev->links = 1; dev->links = 1;
/* Set up the primary, secondary and subordinate bus numbers. We have /* Set up the primary, secondary and subordinate bus numbers. We have

55
src/devices/pci_ops.c Normal file
View File

@ -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);
}

View File

@ -33,7 +33,7 @@ extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
uint32_t __base = (base); \ uint32_t __base = (base); \
uint32_t __rem; \ uint32_t __rem; \
(void)(((typeof((n)) *)0) == ((uint64_t *)0)); \ (void)(((typeof((n)) *)0) == ((uint64_t *)0)); \
if (likely(((n) >> 32) == 0)) { \ if (((n) >> 32) == 0) { \
__rem = (uint32_t)(n) % __base; \ __rem = (uint32_t)(n) % __base; \
(n) = (uint32_t)(n) / __base; \ (n) = (uint32_t)(n) / __base; \
} else \ } else \

View File

@ -2,6 +2,7 @@
#define CPU_CPU_H #define CPU_CPU_H
struct device; struct device;
struct bus;
#include <arch/cpu.h> #include <arch/cpu.h>
void cpu_initialize(void); void cpu_initialize(void);

View File

@ -1,6 +1,6 @@
#ifndef CPU_PPC_CPUID_H #ifndef CPU_PPC_CPUID_H
#define CPU_PPC_CPUID_H #define CPU_PPC_CPUID_H
void display_cpuid(void); void display_cpuid(device_t dev);
#endif /* CPU_PPC_CPUID_H */ #endif /* CPU_PPC_CPUID_H */

View File

@ -9,6 +9,7 @@
struct device; struct device;
typedef struct device * device_t; typedef struct device * device_t;
struct pci_operations; struct pci_operations;
struct pci_bus_operations;
struct smbus_bus_operations; struct smbus_bus_operations;
/* Chip operations */ /* Chip operations */
@ -32,8 +33,9 @@ struct device_operations {
void (*init)(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); void (*enable)(device_t dev);
struct pci_operations *ops_pci; const struct pci_operations *ops_pci;
struct smbus_bus_operations *ops_smbus_bus; const struct smbus_bus_operations *ops_smbus_bus;
const struct pci_bus_operations *ops_pci_bus;
}; };

View File

@ -4,13 +4,14 @@
enum device_path_type { enum device_path_type {
DEVICE_PATH_NONE = 0, DEVICE_PATH_NONE = 0,
DEVICE_PATH_ROOT, DEVICE_PATH_ROOT,
DEVICE_PATH_DEFAULT_CPU,
DEVICE_PATH_PCI, DEVICE_PATH_PCI,
DEVICE_PATH_PNP, DEVICE_PATH_PNP,
DEVICE_PATH_I2C, DEVICE_PATH_I2C,
DEVICE_PATH_APIC, DEVICE_PATH_APIC,
DEVICE_PATH_PCI_DOMAIN, DEVICE_PATH_PCI_DOMAIN,
DEVICE_PATH_APIC_CLUSTER, DEVICE_PATH_APIC_CLUSTER,
DEVICE_PATH_CPU,
DEVICE_PATH_CPU_BUS,
}; };
struct pci_domain_path struct pci_domain_path
@ -44,6 +45,16 @@ struct apic_cluster_path
unsigned cluster; unsigned cluster;
}; };
struct cpu_path
{
unsigned id;
};
struct cpu_bus_path
{
unsigned id;
};
struct device_path { struct device_path {
enum device_path_type type; enum device_path_type type;
@ -54,6 +65,8 @@ struct device_path {
struct apic_path apic; struct apic_path apic;
struct pci_domain_path pci_domain; struct pci_domain_path pci_domain;
struct apic_cluster_path apic_cluster; struct apic_cluster_path apic_cluster;
struct cpu_path cpu;
struct cpu_bus_path cpu_bus;
} u; } u;
}; };

View File

@ -26,6 +26,16 @@ struct pci_operations {
void (*set_subsystem)(device_t dev, unsigned vendor, unsigned device); 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 pci_driver {
struct device_operations *ops; struct device_operations *ops;
unsigned short vendor; 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_IO_BRIDGE_ALIGN 4096
#define PCI_MEM_BRIDGE_ALIGN (1024*1024) #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; pops = 0;
if (dev && dev->ops) { if (dev && dev->ops) {
pops = dev->ops->ops_pci; pops = dev->ops->ops_pci;
@ -65,4 +75,14 @@ static inline struct pci_operations *ops_pci(device_t dev)
return pops; 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 */ #endif /* PCI_H */

View File

@ -20,30 +20,30 @@ object clock.o
arch ppc end arch ppc end
if CONFIG_SANDPOINT_ALTIMUS if CONFIG_SANDPOINT_ALTIMUS
chip pmc/altimus/mpc7410 device pnp 0.0 on end end dir /pmc/altimus/mpc7410
# chip pmc/altimus/mpc7400 device pnp 0.0 on end end # dir /pmc/altimus/mpc7400
# chip pmc/altimus/mpc75x device pnp 0.0 on end end # dir /pmc/altimus/mpc75x
end end
if CONFIG_SANDPOINT_TALUS if CONFIG_SANDPOINT_TALUS
chip pmc/talus/mpc74x device pnp 0.0 on end end dir /pmc/talus/mpc74x
chip pmc/talus/mpc603 device pnp 0.0 on end end dir /pmc/talus/mpc603
end end
if CONFIG_SANDPOINT_UNITY if CONFIG_SANDPOINT_UNITY
chip pmc/unity/mpc824x device pnp 0.0 on end end dir /pmc/unity/mpc824x
end end
if CONFIG_SANDPOINT_VALIS if CONFIG_SANDPOINT_VALIS
chip pmc/valis/mpc745x device pnp 0.0 on end end dir /pmc/valis/mpc745x
end end
if CONFIG_SANDPOINT_GYRUS if CONFIG_SANDPOINT_GYRUS
chip pmc/gyrus/mpc744x device pnp 0.0 on end end dir /pmc/gyrus/mpc744x
end end
## ##
## Include the secondary Configuration files ## 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. ## Build the objects we have code for in this directory.

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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;
}

View File

@ -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

View File

@ -0,0 +1,2 @@
object flash.o
object amd800.o

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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");
}

View File

@ -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

View File

@ -0,0 +1,2 @@
object bsp_nvram.o
object nvram.o

View File

@ -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
};

View File

@ -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();
}

View File

@ -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

View File

@ -16,17 +16,31 @@ object clock.o
arch ppc end arch ppc end
if CONFIG_BRIQ_750FX if CONFIG_BRIQ_750FX
chip cpu/ppc/ppc7xx device pnp 0.0 on end end dir /cpu/ppc/ppc7xx
end end
if CONFIG_BRIQ_7400 if CONFIG_BRIQ_7400
chip cpu/ppc/mpc74xx device pnp 0.0 on end end dir /cpu/ppc/mpc74xx
end end
## ##
## Include the secondary Configuration files ## Include the secondary Configuration files
## ##
chip northbridge/ibm/cpc710 device pnp 0.0 on end end chip northbridge/ibm/cpc710
chip southbridge/winbond/w83c553 device pnp 0.0 on end end 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. ## Build the objects we have code for in this directory.

View File

@ -657,6 +657,7 @@ static struct device_operations pci_domain_ops = {
.enable_resources = enable_childrens_resources, .enable_resources = enable_childrens_resources,
.init = 0, .init = 0,
.scan_bus = pci_domain_scan_bus, .scan_bus = pci_domain_scan_bus,
.ops_pci_bus = &pci_cf8_conf1,
}; };
static unsigned int cpu_bus_scan(device_t dev, unsigned int max) 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 */ /* Set the operations if it is a special bus type */
if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
dev->ops = &pci_domain_ops; dev->ops = &pci_domain_ops;
pci_set_method_conf1();
} }
else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
dev->ops = &cpu_bus_ops; dev->ops = &cpu_bus_ops;

View File

@ -115,7 +115,7 @@ static void enable_dev(struct device *dev)
/* Set the operations if it is a special bus type */ /* Set the operations if it is a special bus type */
if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
dev->ops = &pci_domain_ops; dev->ops = &pci_domain_ops;
pci_set_method(); pci_set_method(dev);
} }
} }

View File

@ -2,10 +2,13 @@
# Config file for IBM CPC710 # Config file for IBM CPC710
# #
config chip.h
initobject cpc710.o initobject cpc710.o
initobject cpc710_pci.o initobject cpc710_pci.o
#initobject cpc710_sdram.o #initobject cpc710_sdram.o
object cpc710.o object cpc710.o
object cpc710_pci.o object cpc710_pci.o
object cpc710_sdram.o #object cpc710_sdram.o
driver cpc710_northbridge.o

View File

@ -0,0 +1,6 @@
struct northbridge_ibm_cpc710_config {
/* Nothing yet */
};
extern struct chip_operations northbridge_ibm_cpc710_ops;

View File

@ -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,
};

View File

@ -8,8 +8,6 @@
#include <bitops.h> #include <bitops.h>
#include "chip.h" #include "chip.h"
#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM)
static void pci_domain_read_resources(device_t dev) static void pci_domain_read_resources(device_t dev)
{ {
struct resource *resource; 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) static void pci_domain_set_resources(device_t dev)
{ {
struct resource *resource, *last;
device_t mc_dev; device_t mc_dev;
uint32_t pci_tolm; uint32_t pci_tolm;
@ -157,6 +154,7 @@ static struct device_operations pci_domain_ops = {
.enable_resources = enable_childrens_resources, .enable_resources = enable_childrens_resources,
.init = 0, .init = 0,
.scan_bus = pci_domain_scan_bus, .scan_bus = pci_domain_scan_bus,
.ops_pci_bus = &pci_cf8_conf1,
}; };
static void cpu_bus_init(device_t dev) 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 */ /* Set the operations if it is a special bus type */
if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
dev->ops = &pci_domain_ops; dev->ops = &pci_domain_ops;
pci_set_method_conf1();
} }
else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
dev->ops = &cpu_bus_ops; dev->ops = &cpu_bus_ops;

View File

@ -149,7 +149,7 @@ static void enable_dev(struct device *dev)
/* Set the operations if it is a special bus type */ /* Set the operations if it is a special bus type */
if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
dev->ops = &pci_domain_ops; dev->ops = &pci_domain_ops;
pci_set_method(); pci_set_method(dev);
} }
else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
dev->ops = &cpu_bus_ops; dev->ops = &cpu_bus_ops;

View File

@ -2,10 +2,9 @@
# Objects linked with linuxbios # Objects linked with linuxbios
# #
config chip.h
# We need sdram_init() in ppc_main() # We need sdram_init() in ppc_main()
initobject meminfo.o initobject meminfo.o
initobject mpc107.o initobject mpc107.o
# We need sizeram() in hardwaremain() object mpc107_northbridge.c
object meminfo.o
object mpc107.o

View File

@ -25,7 +25,6 @@
#include <arch/pciconf.h> #include <arch/pciconf.h>
#include <timer.h> #include <timer.h>
#include <clock.h> #include <clock.h>
#include <mem.h>
#include "i2c.h" #include "i2c.h"
#include "mpc107.h" #include "mpc107.h"
@ -45,27 +44,6 @@ memory_init(void)
(void)mpc107_config_memory(NUM_BANKS, banks, 2); (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 * Configure the MPC107 with the most pessimistic settings. These
* are modified by reading the SPD EEPROM and adjusting accordingly. * are modified by reading the SPD EEPROM and adjusting accordingly.

View File

@ -142,7 +142,7 @@ static void enable_dev(struct device *dev)
/* Set the operations if it is a special bus type */ /* Set the operations if it is a special bus type */
if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
dev->ops = &pci_domain_ops; dev->ops = &pci_domain_ops;
pci_set_method(); pci_set_method(dev);
} }
else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
dev->ops = &cpu_bus_ops; dev->ops = &cpu_bus_ops;

View File

@ -186,7 +186,7 @@ static void enable_dev(struct device *dev)
/* Set the operations if it is a special bus type */ /* Set the operations if it is a special bus type */
if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
dev->ops = &pci_domain_ops; dev->ops = &pci_domain_ops;
pci_set_method(); pci_set_method(dev);
} }
else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
dev->ops = &cpu_bus_ops; dev->ops = &cpu_bus_ops;

View File

@ -268,7 +268,7 @@ static void enable_dev(struct device *dev)
/* Set the operations if it is a special bus type */ /* Set the operations if it is a special bus type */
if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
dev->ops = &pci_domain_ops; dev->ops = &pci_domain_ops;
pci_set_method(); pci_set_method(dev);
} }
else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
dev->ops = &cpu_bus_ops; dev->ops = &cpu_bus_ops;

View File

@ -26,7 +26,6 @@ static int kbd_empty_output_buffer(void)
static void pc_keyboard_init(struct pc_keyboard *keyboard) static void pc_keyboard_init(struct pc_keyboard *keyboard)
{ {
unsigned char regval; unsigned char regval;
unsigned long timeout;
/* send cmd = 0xAA, self test 8042 */ /* send cmd = 0xAA, self test 8042 */
outb(0xaa, 0x64); outb(0xaa, 0x64);

View File

@ -1,12 +1,12 @@
## ##
## CPU initialization ## CPU initialization
## ##
chip cpu/ppc/mpc74xx device pnp 0.0 on end end dir /cpu/ppc/mpc74xx
## ##
## Include the secondary Configuration files ## 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. ## Build the objects we have code for in this directory.

View File

@ -3,6 +3,8 @@
#include <arch/io.h> #include <arch/io.h>
#include <console/console.h> #include <console/console.h>
#include <device/device.h>
#include <device/pnp.h>
#include "chip.h" #include "chip.h"
#include "pc97307.h" #include "pc97307.h"
@ -14,7 +16,7 @@ static void init(device_t dev)
if (!dev->enabled) { if (!dev->enabled) {
return; return;
} }
conf = dev->chip; conf = dev->chip_info;
switch(dev->path.u.pnp.device) { switch(dev->path.u.pnp.device) {
case PC97307_SP1: case PC97307_SP1:
res0 = find_resource(dev, PNP_IDX_IO0); res0 = find_resource(dev, PNP_IDX_IO0);
@ -39,6 +41,8 @@ static void init(device_t dev)
break; break;
case PC97307_FDC: case PC97307_FDC:
{
unsigned reg;
/* Set up floppy in PS/2 mode */ /* Set up floppy in PS/2 mode */
outb(0x09, SIO_CONFIG_RA); outb(0x09, SIO_CONFIG_RA);
reg = inb(SIO_CONFIG_RD); 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);
outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */ outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */
break; 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); 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") CHIP_NAME("NSC 97307")
.enable_dev = enable_dev, .enable_dev = enable_dev,
}; };