mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
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:
parent
9342d1be4e
commit
7102949d76
7 changed files with 95 additions and 1369 deletions
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue