We're much closer.

Added a stepping enum to k8.h. This will allow us to do things like this:
if (cpu_stepping(node) < E0)

and so on instead of is_cpu_pre_e0_in_bsp or whatever it is. 

Added and fixed Kconfig variables. 

Broke out northbridge by function, so we can see what goes with what. 

This tree still builds a working DBE62 coreboot that boots a kernel; no harm done to existing ports. 

Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Acked-by: Ronald G. Minnich <rminnich@gmail.com>



git-svn-id: svn://coreboot.org/repository/coreboot-v3@781 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
Ronald G. Minnich 2008-08-17 22:18:09 +00:00
parent 9342d1be4e
commit 7102949d76
7 changed files with 95 additions and 1369 deletions

View file

@ -224,6 +224,6 @@ config USBDEBUG_DIRECT
config APIC_ID_OFFSET
hex "APIC ID offset"
default 0x10
depends IO_APIC
depends IOAPIC
help
This is entirely mainboard dependent. 0x10 is a *typical* setting but not always a good setting.

View file

@ -304,6 +304,16 @@
#define ConnectionPending (1 << 4)
#ifndef ASSEMBLY
/* Steppings of the K8 cpu */
enum steppings {
A0,
A1,
A2,
B0,
C0,
CG,
};
/* cpu version -- no support for f0 yet */
static inline int is_cpu_rev_a0(void)
{
@ -391,22 +401,22 @@ struct mem_controller {
};
struct link_pair_st {
u32 udev;
u32 upos;
u32 uoffs;
u32 dev;
u32 pos;
u32 offs;
u32 udev;
u32 upos;
u32 uoffs;
u32 dev;
u32 pos;
u32 offs;
} __attribute__((packed));
struct sys_info {
u8 ctrl_present[NODE_NUMS];
struct mem_info meminfo[NODE_NUMS];
u8 ctrl_present[NODE_NUMS];
struct mem_info meminfo[NODE_NUMS];
struct mem_controller ctrl[NODE_NUMS];
u8 mem_trained[NODE_NUMS]; //0: no dimm, 1: trained, 0x80: not started, 0x81: recv1 fail, 0x82: Pos Fail, 0x83:recv2 fail
u32 tom_k;
u32 tom2_k;
u32 tom_k;
u32 tom2_k;
u32 mem_base[NODE_NUMS];
u32 cs_base[NODE_NUMS*8]; //8 cs_idx
@ -415,9 +425,9 @@ struct sys_info {
u8 dqs_delay_a[NODE_NUMS*2*2*9]; //8 node channel 2, direction 2 , bytelane *9
u8 dqs_rcvr_dly_a[NODE_NUMS*2*8]; //8 node, channel 2, receiver 8
u32 nodes;
struct link_pair_st link_pair[16];// enough? only in_conherent
u32 link_pair_num;
u32 ht_c_num;
struct link_pair_st link_pair[16];// enough? only in_conherent
u32 link_pair_num;
u32 ht_c_num;
u32 sbdn;
u32 sblk;
u32 sbbusn;

View file

@ -54,6 +54,7 @@ config BOARD_AMD_SERENGETI
select NORTHBRIDGE_AMD_K8
select SOUTHBRIDGE_AMD_AMD8111
select IOAPIC
select APIC_ID_OFFSET
help
AMD Serengeti

File diff suppressed because it is too large Load diff

View file

@ -28,6 +28,7 @@
2005.11 yhlu add put sb ht chain on bus 0
*/
#include <config.h>
#include <console.h>
#include <lib.h>
#include <string.h>

View file

@ -45,6 +45,59 @@
#include <lib.h>
#include <lapic.h>
#ifdef CONFIG_PCI_64BIT_PREF_MEM
#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH)
#endif
#define FX_DEVS 8
extern struct device * __f0_dev[FX_DEVS];
extern struct device * __f1_dev[FX_DEVS];
void debug_fx_devs(void);
void get_fx_devs(void);
u32 f1_read_config32(unsigned int reg);
void f1_write_config32(unsigned int reg, u32 value);
unsigned int amdk8_nodeid(struct device * dev);
static void k8_ram_resource(struct device * 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 tolm_test(void *gp, struct device *dev, struct resource *new)
{
struct resource **best_p = gp;
struct resource *best;
best = *best_p;
if (!best || (best->base > new->base)) {
best = new;
}
*best_p = best;
}
static u32 find_pci_tolm(struct bus *bus)
{
struct resource *min;
u32 tolm;
min = 0;
search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
tolm = 0xffffffffUL;
if (min && tolm > min->base) {
tolm = min->base;
}
return tolm;
}
static void k8_pci_domain_read_resources(struct device * dev)
{
struct resource *resource;

View file

@ -49,70 +49,14 @@
#include <cpu/amd/model_fxx_rev.h>
#endif
struct amdk8_sysconf sysconf;
#define FX_DEVS 8
static struct device * __f0_dev[FX_DEVS];
static struct device * __f1_dev[FX_DEVS];
#if 0
static void debug_fx_devs(void)
{
int i;
for(i = 0; i < FX_DEVS; i++) {
struct device * dev;
dev = __f0_dev[i];
if (dev) {
printk(BIOS_DEBUG, "__f0_dev[%d]: %s bus: %p\n",
i, dev_path(dev), dev->bus);
}
dev = __f1_dev[i];
if (dev) {
printk(BIOS_DEBUG, "__f1_dev[%d]: %s bus: %p\n",
i, dev_path(dev), dev->bus);
}
}
}
#endif
static void get_fx_devs(void)
{
int i;
if (__f1_dev[0]) {
return;
}
for(i = 0; i < FX_DEVS; i++) {
__f0_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 0));
__f1_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 1));
}
if (!__f1_dev[0]) {
die("Cannot find 0:0x18.1\n");
}
}
static u32 f1_read_config32(unsigned reg)
{
get_fx_devs();
return pci_read_config32(__f1_dev[0], reg);
}
static void f1_write_config32(unsigned reg, u32 value)
{
int i;
get_fx_devs();
for(i = 0; i < FX_DEVS; i++) {
struct device * dev;
dev = __f1_dev[i];
if (dev && dev->enabled) {
pci_write_config32(dev, reg, value);
}
}
}
static unsigned int amdk8_nodeid(struct device * dev)
{
return (dev->path.pci.devfn >> 3) - 0x18;
}
extern struct device * __f0_dev[FX_DEVS];
extern struct device * __f1_dev[FX_DEVS];
void debug_fx_devs(void);
void get_fx_devs(void);
u32 f1_read_config32(unsigned int reg);
void f1_write_config32(unsigned int reg, u32 value);
unsigned int amdk8_nodeid(struct device * dev);
static unsigned int amdk8_scan_chain(struct device * dev, unsigned nodeid, unsigned link, unsigned sblink, unsigned int max, unsigned offset_unitid)
{
@ -527,7 +471,7 @@ static void amdk8_set_resource(struct device * dev, struct resource *resource, u
* I tried to reuse the resource allocation code in amdk8_set_resource()
* but it is too diffcult to deal with the resource allocation magic.
*/
#if CONFIG_MULTIPLE_VGA_INIT == 1
#ifdef CONFIG_MULTIPLE_VGA_INIT
extern struct device * vga_pri; // the primary vga device, defined in device.c
#endif
@ -542,7 +486,7 @@ static void amdk8_create_vga_resource(struct device * dev, unsigned nodeid)
* we only deal with the 'first' vga card */
for (link = 0; link < dev->links; link++) {
if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
#if CONFIG_MULTIPLE_VGA_INIT == 1
#ifdef CONFIG_MULTIPLE_VGA_INIT
printk(BIOS_DEBUG, "VGA: vga_pri bus num = %d dev->link[link] bus range [%d,%d]\n", vga_pri->bus->secondary,
dev->link[link].secondary,dev->link[link].subordinate);
/* We need to make sure the vga_pri is under the link */
@ -624,198 +568,10 @@ static void mcf0_control_init(struct device *dev)
printk(BIOS_DEBUG, "done.\n");
}
static void k8_ram_resource(struct device * 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 tolm_test(void *gp, struct device *dev, struct resource *new)
{
struct resource **best_p = gp;
struct resource *best;
best = *best_p;
if (!best || (best->base > new->base)) {
best = new;
}
*best_p = best;
}
static u32 find_pci_tolm(struct bus *bus)
{
struct resource *min;
u32 tolm;
min = 0;
search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
tolm = 0xffffffffUL;
if (min && tolm > min->base) {
tolm = min->base;
}
return tolm;
}
#ifdef CONFIG_PCI_64BIT_PREF_MEM
#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH)
#endif
#if CONFIG_HW_MEM_HOLE_SIZEK != 0
struct hw_mem_hole_info {
unsigned hole_startk;
int node_id;
};
static struct hw_mem_hole_info get_hw_mem_hole_info(void)
{
struct hw_mem_hole_info mem_hole;
int i;
mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK;
mem_hole.node_id = -1;
for (i = 0; i < 8; i++) {
u32 base;
u32 hole;
base = f1_read_config32(0x40 + (i << 3));
if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
continue;
}
hole = pci_read_config32(__f1_dev[i], 0xf0);
if(hole & 1) { // we find the hole
mem_hole.hole_startk = (hole & (0xff<<24)) >> 10;
mem_hole.node_id = i; // record the node No with hole
break; // only one hole
}
}
//We need to double check if there is speical set on base reg and limit reg are not continous instead of hole, it will find out it's hole_startk
if(mem_hole.node_id==-1) {
u32 limitk_pri = 0;
for(i=0; i<8; i++) {
u32 base, limit;
unsigned base_k, limit_k;
base = f1_read_config32(0x40 + (i << 3));
if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
continue;
}
base_k = (base & 0xffff0000) >> 2;
if(limitk_pri != base_k) { // we find the hole
mem_hole.hole_startk = limitk_pri;
mem_hole.node_id = i;
break; //only one hole
}
limit = f1_read_config32(0x44 + (i << 3));
limit_k = ((limit + 0x00010000) & 0xffff0000) >> 2;
limitk_pri = limit_k;
}
}
return mem_hole;
}
static void disable_hoist_memory(unsigned long hole_startk, int i)
{
int ii;
struct device * dev;
u32 base, limit;
u32 hoist;
u32 hole_sizek;
//1. find which node has hole
//2. change limit in that node.
//3. change base and limit in later node
//4. clear that node f0
//if there is not mem hole enabled, we need to change it's base instead
hole_sizek = (4*1024*1024) - hole_startk;
for(ii=7;ii>i;ii--) {
base = f1_read_config32(0x40 + (ii << 3));
if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
continue;
}
limit = f1_read_config32(0x44 + (ii << 3));
f1_write_config32(0x44 + (ii << 3),limit - (hole_sizek << 2));
f1_write_config32(0x40 + (ii << 3),base - (hole_sizek << 2));
}
limit = f1_read_config32(0x44 + (i << 3));
f1_write_config32(0x44 + (i << 3),limit - (hole_sizek << 2));
dev = __f1_dev[i];
hoist = pci_read_config32(dev, 0xf0);
if(hoist & 1) {
pci_write_config32(dev, 0xf0, 0);
}
else {
base = pci_read_config32(dev, 0x40 + (i << 3));
f1_write_config32(0x40 + (i << 3),base - (hole_sizek << 2));
}
}
static u32 hoist_memory(unsigned long hole_startk, int i)
{
int ii;
u32 carry_over;
struct device * dev;
u32 base, limit;
u32 basek;
u32 hoist;
carry_over = (4*1024*1024) - hole_startk;
for(ii=7;ii>i;ii--) {
base = f1_read_config32(0x40 + (ii << 3));
if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
continue;
}
limit = f1_read_config32(0x44 + (ii << 3));
f1_write_config32(0x44 + (ii << 3),limit + (carry_over << 2));
f1_write_config32(0x40 + (ii << 3),base + (carry_over << 2));
}
limit = f1_read_config32(0x44 + (i << 3));
f1_write_config32(0x44 + (i << 3),limit + (carry_over << 2));
dev = __f1_dev[i];
base = pci_read_config32(dev, 0x40 + (i << 3));
basek = (base & 0xffff0000) >> 2;
if(basek == hole_startk) {
//don't need set memhole here, because hole off set will be 0, overflow
//so need to change base reg instead, new basek will be 4*1024*1024
base &= 0x0000ffff;
base |= (4*1024*1024)<<2;
f1_write_config32(0x40 + (i<<3), base);
}
else
{
hoist = /* hole start address */
((hole_startk << 10) & 0xff000000) +
/* hole address to memory controller address */
(((basek + carry_over) >> 6) & 0x0000ff00) +
/* enable */
1;
pci_write_config32(dev, 0xf0, hoist);
}
return carry_over;
}
#endif
struct device_operations k8_ops = {
.id = {.type = DEVICE_ID_PCI,
{.pci = {.vendor = PCI_VENDOR_ID_AMD,