- ldscripb.lb remove another $Id: line..
- romcc_io.h Add include guards. - hdama/Config nothing really but I have been moving the setting back and forth between 1 and 2 cpus - auto.c Changed the enabled debugging comments. This almost works with 2 cpus - coherent_ht.c First pass at getting this right. It can now find 2 cpus and place them in some semblance of a working state. - raminit.c Fix problems with 4GB of ram. Disable some of the debugging code. git-svn-id: svn://svn.coreboot.org/coreboot/trunk@965 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
61b29a9b72
commit
91a8ce7d80
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef ARCH_ROMCC_IO_H
|
||||||
|
#define ARCH_ROMCC_IO_H 1
|
||||||
|
|
||||||
static void outb(unsigned char value, unsigned short port)
|
static void outb(unsigned char value, unsigned short port)
|
||||||
{
|
{
|
||||||
__builtin_outb(value, port);
|
__builtin_outb(value, port);
|
||||||
|
@ -182,3 +185,4 @@ static device_t pci_locate_device(unsigned pci_id, device_t dev)
|
||||||
return PCI_DEV_INVALID;
|
return PCI_DEV_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* ARCH_ROMCC_IO_H */
|
||||||
|
|
|
@ -9,165 +9,6 @@
|
||||||
#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
|
#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
|
||||||
#include "northbridge/amd/amdk8/raminit.h"
|
#include "northbridge/amd/amdk8/raminit.h"
|
||||||
|
|
||||||
#warning "FIXME move these delay functions somewhere more appropriate"
|
|
||||||
#warning "FIXME use the apic timer instead it needs no calibration on an Opteron it runs at 200Mhz"
|
|
||||||
static void print_clock_multiplier(void)
|
|
||||||
{
|
|
||||||
msr_t msr;
|
|
||||||
print_debug("clock multipler: 0x");
|
|
||||||
msr = rdmsr(0xc0010042);
|
|
||||||
print_debug_hex32(msr.lo & 0x3f);
|
|
||||||
print_debug(" = 0x");
|
|
||||||
print_debug_hex32(((msr.lo & 0x3f) + 8) * 100);
|
|
||||||
print_debug("Mhz\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned usecs_to_ticks(unsigned usecs)
|
|
||||||
{
|
|
||||||
#warning "FIXME make usecs_to_ticks work properly"
|
|
||||||
#if 1
|
|
||||||
return usecs *2000;
|
|
||||||
#else
|
|
||||||
/* This can only be done if cpuid says fid changing is supported
|
|
||||||
* I need to look up the base frequency another way for other
|
|
||||||
* cpus. Is it worth dedicating a global register to this?
|
|
||||||
* Are the PET timers useable for this purpose?
|
|
||||||
*/
|
|
||||||
msr_t msr;
|
|
||||||
msr = rdmsr(0xc0010042);
|
|
||||||
return ((msr.lo & 0x3f) + 8) * 100 *usecs;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_apic_timer(void)
|
|
||||||
{
|
|
||||||
volatile uint32_t *apic_reg = (volatile uint32_t *)0xfee00000;
|
|
||||||
uint32_t start, end;
|
|
||||||
/* Set the apic timer to no interrupts and periodic mode */
|
|
||||||
apic_reg[0x320 >> 2] = (1 << 17)|(1<< 16)|(0 << 12)|(0 << 0);
|
|
||||||
/* Set the divider to 1, no divider */
|
|
||||||
apic_reg[0x3e0 >> 2] = (1 << 3) | 3;
|
|
||||||
/* Set the initial counter to 0xffffffff */
|
|
||||||
apic_reg[0x380 >> 2] = 0xffffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void udelay(unsigned usecs)
|
|
||||||
{
|
|
||||||
#if 1
|
|
||||||
uint32_t start, ticks;
|
|
||||||
tsc_t tsc;
|
|
||||||
/* Calculate the number of ticks to run for */
|
|
||||||
ticks = usecs_to_ticks(usecs);
|
|
||||||
/* Find the current time */
|
|
||||||
tsc = rdtsc();
|
|
||||||
start = tsc.lo;
|
|
||||||
do {
|
|
||||||
tsc = rdtsc();
|
|
||||||
} while((tsc.lo - start) < ticks);
|
|
||||||
#else
|
|
||||||
volatile uint32_t *apic_reg = (volatile uint32_t *)0xfee00000;
|
|
||||||
uint32_t start, value, ticks;
|
|
||||||
/* Calculate the number of ticks to run for */
|
|
||||||
ticks = usecs * 200;
|
|
||||||
start = apic_reg[0x390 >> 2];
|
|
||||||
do {
|
|
||||||
value = apic_reg[0x390 >> 2];
|
|
||||||
} while((start - value) < ticks);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mdelay(unsigned msecs)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < msecs; i++) {
|
|
||||||
udelay(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void delay(unsigned secs)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < secs; i++) {
|
|
||||||
mdelay(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void memreset_setup(const struct mem_controller *ctrl)
|
|
||||||
{
|
|
||||||
/* Set the memreset low */
|
|
||||||
outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 28);
|
|
||||||
/* Ensure the BIOS has control of the memory lines */
|
|
||||||
outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 29);
|
|
||||||
print_debug("memreset lo\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void memreset(const struct mem_controller *ctrl)
|
|
||||||
{
|
|
||||||
udelay(800);
|
|
||||||
/* Set memreset_high */
|
|
||||||
outb((0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 28);
|
|
||||||
print_debug("memreset hi\r\n");
|
|
||||||
udelay(50);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#include "northbridge/amd/amdk8/raminit.c"
|
|
||||||
#include "northbridge/amd/amdk8/coherent_ht.c"
|
|
||||||
#include "sdram/generic_sdram.c"
|
|
||||||
|
|
||||||
#define NODE_ID 0x60
|
|
||||||
#define HT_INIT_CONTROL 0x6c
|
|
||||||
|
|
||||||
#define HTIC_ColdR_Detect (1<<4)
|
|
||||||
#define HTIC_BIOSR_Detect (1<<5)
|
|
||||||
#define HTIC_INIT_Detect (1<<6)
|
|
||||||
|
|
||||||
static int boot_cpu(void)
|
|
||||||
{
|
|
||||||
volatile unsigned long *local_apic;
|
|
||||||
unsigned long apic_id;
|
|
||||||
int bsp;
|
|
||||||
msr_t msr;
|
|
||||||
msr = rdmsr(0x1b);
|
|
||||||
bsp = !!(msr.lo & (1 << 8));
|
|
||||||
if (bsp) {
|
|
||||||
print_debug("Bootstrap cpu\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return bsp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cpu_init_detected(void)
|
|
||||||
{
|
|
||||||
unsigned long dcl;
|
|
||||||
int cpu_init;
|
|
||||||
|
|
||||||
unsigned long htic;
|
|
||||||
|
|
||||||
htic = pci_read_config32(PCI_DEV(0, 0x18, 0), HT_INIT_CONTROL);
|
|
||||||
#if 0
|
|
||||||
print_debug("htic: ");
|
|
||||||
print_debug_hex32(htic);
|
|
||||||
print_debug("\r\n");
|
|
||||||
|
|
||||||
if (!(htic & HTIC_ColdR_Detect)) {
|
|
||||||
print_debug("Cold Reset.\r\n");
|
|
||||||
}
|
|
||||||
if ((htic & HTIC_ColdR_Detect) && !(htic & HTIC_BIOSR_Detect)) {
|
|
||||||
print_debug("BIOS generated Reset.\r\n");
|
|
||||||
}
|
|
||||||
if (htic & HTIC_INIT_Detect) {
|
|
||||||
print_debug("Init event.\r\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
cpu_init = (htic & HTIC_INIT_Detect);
|
|
||||||
if (cpu_init) {
|
|
||||||
print_debug("CPU INIT Detected.\r\n");
|
|
||||||
}
|
|
||||||
return cpu_init;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void print_debug_pci_dev(unsigned dev)
|
static void print_debug_pci_dev(unsigned dev)
|
||||||
{
|
{
|
||||||
|
@ -197,7 +38,6 @@ static void print_pci_devices(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void dump_pci_device(unsigned dev)
|
static void dump_pci_device(unsigned dev)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -297,6 +137,165 @@ static void dump_spd_registers(const struct mem_controller *ctrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#warning "FIXME move these delay functions somewhere more appropriate"
|
||||||
|
#warning "FIXME use the apic timer instead it needs no calibration on an Opteron it runs at 200Mhz"
|
||||||
|
static void print_clock_multiplier(void)
|
||||||
|
{
|
||||||
|
msr_t msr;
|
||||||
|
print_debug("clock multipler: 0x");
|
||||||
|
msr = rdmsr(0xc0010042);
|
||||||
|
print_debug_hex32(msr.lo & 0x3f);
|
||||||
|
print_debug(" = 0x");
|
||||||
|
print_debug_hex32(((msr.lo & 0x3f) + 8) * 100);
|
||||||
|
print_debug("Mhz\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned usecs_to_ticks(unsigned usecs)
|
||||||
|
{
|
||||||
|
#warning "FIXME make usecs_to_ticks work properly"
|
||||||
|
#if 1
|
||||||
|
return usecs *2000;
|
||||||
|
#else
|
||||||
|
/* This can only be done if cpuid says fid changing is supported
|
||||||
|
* I need to look up the base frequency another way for other
|
||||||
|
* cpus. Is it worth dedicating a global register to this?
|
||||||
|
* Are the PET timers useable for this purpose?
|
||||||
|
*/
|
||||||
|
msr_t msr;
|
||||||
|
msr = rdmsr(0xc0010042);
|
||||||
|
return ((msr.lo & 0x3f) + 8) * 100 *usecs;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_apic_timer(void)
|
||||||
|
{
|
||||||
|
volatile uint32_t *apic_reg = (volatile uint32_t *)0xfee00000;
|
||||||
|
uint32_t start, end;
|
||||||
|
/* Set the apic timer to no interrupts and periodic mode */
|
||||||
|
apic_reg[0x320 >> 2] = (1 << 17)|(1<< 16)|(0 << 12)|(0 << 0);
|
||||||
|
/* Set the divider to 1, no divider */
|
||||||
|
apic_reg[0x3e0 >> 2] = (1 << 3) | 3;
|
||||||
|
/* Set the initial counter to 0xffffffff */
|
||||||
|
apic_reg[0x380 >> 2] = 0xffffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void udelay(unsigned usecs)
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
uint32_t start, ticks;
|
||||||
|
tsc_t tsc;
|
||||||
|
/* Calculate the number of ticks to run for */
|
||||||
|
ticks = usecs_to_ticks(usecs);
|
||||||
|
/* Find the current time */
|
||||||
|
tsc = rdtsc();
|
||||||
|
start = tsc.lo;
|
||||||
|
do {
|
||||||
|
tsc = rdtsc();
|
||||||
|
} while((tsc.lo - start) < ticks);
|
||||||
|
#else
|
||||||
|
volatile uint32_t *apic_reg = (volatile uint32_t *)0xfee00000;
|
||||||
|
uint32_t start, value, ticks;
|
||||||
|
/* Calculate the number of ticks to run for */
|
||||||
|
ticks = usecs * 200;
|
||||||
|
start = apic_reg[0x390 >> 2];
|
||||||
|
do {
|
||||||
|
value = apic_reg[0x390 >> 2];
|
||||||
|
} while((start - value) < ticks);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mdelay(unsigned msecs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < msecs; i++) {
|
||||||
|
udelay(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void delay(unsigned secs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < secs; i++) {
|
||||||
|
mdelay(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void memreset_setup(const struct mem_controller *ctrl)
|
||||||
|
{
|
||||||
|
/* Set the memreset low */
|
||||||
|
outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 28);
|
||||||
|
/* Ensure the BIOS has control of the memory lines */
|
||||||
|
outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 29);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void memreset(const struct mem_controller *ctrl)
|
||||||
|
{
|
||||||
|
udelay(800);
|
||||||
|
/* Set memreset_high */
|
||||||
|
outb((0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 28);
|
||||||
|
udelay(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include "northbridge/amd/amdk8/raminit.c"
|
||||||
|
#include "northbridge/amd/amdk8/coherent_ht.c"
|
||||||
|
#include "sdram/generic_sdram.c"
|
||||||
|
|
||||||
|
#define NODE_ID 0x60
|
||||||
|
#define HT_INIT_CONTROL 0x6c
|
||||||
|
|
||||||
|
#define HTIC_ColdR_Detect (1<<4)
|
||||||
|
#define HTIC_BIOSR_Detect (1<<5)
|
||||||
|
#define HTIC_INIT_Detect (1<<6)
|
||||||
|
|
||||||
|
static int boot_cpu(void)
|
||||||
|
{
|
||||||
|
volatile unsigned long *local_apic;
|
||||||
|
unsigned long apic_id;
|
||||||
|
int bsp;
|
||||||
|
msr_t msr;
|
||||||
|
msr = rdmsr(0x1b);
|
||||||
|
bsp = !!(msr.lo & (1 << 8));
|
||||||
|
if (bsp) {
|
||||||
|
print_debug("Bootstrap cpu\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return bsp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cpu_init_detected(void)
|
||||||
|
{
|
||||||
|
unsigned long dcl;
|
||||||
|
int cpu_init;
|
||||||
|
|
||||||
|
unsigned long htic;
|
||||||
|
|
||||||
|
htic = pci_read_config32(PCI_DEV(0, 0x18, 0), HT_INIT_CONTROL);
|
||||||
|
#if 0
|
||||||
|
print_debug("htic: ");
|
||||||
|
print_debug_hex32(htic);
|
||||||
|
print_debug("\r\n");
|
||||||
|
|
||||||
|
if (!(htic & HTIC_ColdR_Detect)) {
|
||||||
|
print_debug("Cold Reset.\r\n");
|
||||||
|
}
|
||||||
|
if ((htic & HTIC_ColdR_Detect) && !(htic & HTIC_BIOSR_Detect)) {
|
||||||
|
print_debug("BIOS generated Reset.\r\n");
|
||||||
|
}
|
||||||
|
if (htic & HTIC_INIT_Detect) {
|
||||||
|
print_debug("Init event.\r\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
cpu_init = (htic & HTIC_INIT_Detect);
|
||||||
|
if (cpu_init) {
|
||||||
|
print_debug("CPU INIT Detected.\r\n");
|
||||||
|
}
|
||||||
|
return cpu_init;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void pnp_write_config(unsigned char port, unsigned char value, unsigned char reg)
|
static void pnp_write_config(unsigned char port, unsigned char value, unsigned char reg)
|
||||||
{
|
{
|
||||||
outb(reg, port);
|
outb(reg, port);
|
||||||
|
@ -397,18 +396,30 @@ static void main(void)
|
||||||
uart_init();
|
uart_init();
|
||||||
console_init();
|
console_init();
|
||||||
if (boot_cpu() && !cpu_init_detected()) {
|
if (boot_cpu() && !cpu_init_detected()) {
|
||||||
#if 1
|
#if 0
|
||||||
init_apic_timer();
|
init_apic_timer();
|
||||||
#endif
|
#endif
|
||||||
|
#if 1
|
||||||
setup_default_resource_map();
|
setup_default_resource_map();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
dump_pci_device(PCI_DEV(0, 0x18, 0));
|
||||||
|
#endif
|
||||||
|
|
||||||
setup_coherent_ht_domain();
|
setup_coherent_ht_domain();
|
||||||
|
#if 1
|
||||||
|
disable_probes();
|
||||||
|
#endif
|
||||||
enumerate_ht_chain();
|
enumerate_ht_chain();
|
||||||
print_pci_devices();
|
print_pci_devices();
|
||||||
enable_smbus();
|
enable_smbus();
|
||||||
|
#if 0
|
||||||
dump_spd_registers(&cpu0);
|
dump_spd_registers(&cpu0);
|
||||||
|
#endif
|
||||||
sdram_initialize(&cpu0);
|
sdram_initialize(&cpu0);
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
dump_pci_devices();
|
dump_pci_devices();
|
||||||
#endif
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -416,22 +427,21 @@ static void main(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Check all of memory */
|
/* Check all of memory */
|
||||||
|
#if 0
|
||||||
msr_t msr;
|
msr_t msr;
|
||||||
msr = rdmsr(TOP_MEM);
|
msr = rdmsr(TOP_MEM);
|
||||||
print_debug("TOP_MEM: ");
|
print_debug("TOP_MEM: ");
|
||||||
print_debug_hex32(msr.hi);
|
print_debug_hex32(msr.hi);
|
||||||
print_debug_hex32(msr.lo);
|
print_debug_hex32(msr.lo);
|
||||||
print_debug("\r\n");
|
print_debug("\r\n");
|
||||||
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
ram_check(0x00000000, msr.lo);
|
ram_check(0x00000000, msr.lo);
|
||||||
#else
|
#else
|
||||||
|
#if 1
|
||||||
/* Check 16MB of memory */
|
/* Check 16MB of memory */
|
||||||
ram_check(0x00000000, 0x1600000);
|
ram_check(0x00000000, 0x01000000);
|
||||||
#endif
|
#endif
|
||||||
#if 0
|
|
||||||
print_debug("sleeping 15s\r\n");
|
|
||||||
delay(15);
|
|
||||||
print_debug("sleeping 15s done\r\n");
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#if 0
|
||||||
static void setup_coherent_ht_domain(void)
|
static void setup_coherent_ht_domain(void)
|
||||||
{
|
{
|
||||||
static const unsigned int register_values[] = {
|
static const unsigned int register_values[] = {
|
||||||
|
@ -127,7 +128,7 @@ static void setup_coherent_ht_domain(void)
|
||||||
*/
|
*/
|
||||||
PCI_ADDR(0, 0x18, 0, 0x68), 0x00800000, 0x0f00840f,
|
PCI_ADDR(0, 0x18, 0, 0x68), 0x00800000, 0x0f00840f,
|
||||||
/* HT Initialization Control Register
|
/* HT Initialization Control Register
|
||||||
* F0:0x6C
|
* F0:0x6C ok...
|
||||||
* [ 0: 0] Routing Table Disable
|
* [ 0: 0] Routing Table Disable
|
||||||
* 0 = Packets are routed according to routing tables
|
* 0 = Packets are routed according to routing tables
|
||||||
* 1 = Packets are routed according to the default link field
|
* 1 = Packets are routed according to the default link field
|
||||||
|
@ -326,3 +327,513 @@ static void setup_coherent_ht_domain(void)
|
||||||
}
|
}
|
||||||
print_debug("done.\r\n");
|
print_debug("done.\r\n");
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
/* coherent hypertransport initialization for AMD64
|
||||||
|
* written by Stefan Reinauer <stepan@openbios.info>
|
||||||
|
* (c) 2003 by SuSE Linux AG
|
||||||
|
*
|
||||||
|
* This code is licensed under GPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This algorithm assumes a grid configuration as follows:
|
||||||
|
*
|
||||||
|
* nodes : 1 2 4 6 8
|
||||||
|
* org. : 1x1 2x1 2x2 2x3 2x4
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#include "compat.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <device/pci_def.h>
|
||||||
|
#include "arch/romcc_io.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* when generating a temporary row configuration we
|
||||||
|
* don't want broadcast to be enabled for that node.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define generate_temp_row(x...) ((generate_row(x)&(~0x0f0000))|0x010000)
|
||||||
|
#define clear_temp_row(x) fill_row(x,7,DEFAULT)
|
||||||
|
#define enable_bsp_routing() enable_routing(0)
|
||||||
|
|
||||||
|
#define NODE_HT(x) PCI_DEV(0,24+x,0)
|
||||||
|
#define NODE_MP(x) PCI_DEV(0,24+x,1)
|
||||||
|
#define NODE_MC(x) PCI_DEV(0,24+x,3)
|
||||||
|
|
||||||
|
#define DEFAULT 0x00010101 /* default row entry */
|
||||||
|
|
||||||
|
typedef uint8_t u8;
|
||||||
|
typedef uint32_t u32;
|
||||||
|
typedef int8_t bool;
|
||||||
|
|
||||||
|
#define TRUE (-1)
|
||||||
|
#define FALSE (0)
|
||||||
|
|
||||||
|
static void disable_probes(void)
|
||||||
|
{
|
||||||
|
/* disable read/write/fill probes for uniprocessor setup
|
||||||
|
* they don't make sense if only one cpu is available
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Hypetransport Transaction Control Register
|
||||||
|
* F0:0x68
|
||||||
|
* [ 0: 0] Disable read byte probe
|
||||||
|
* 0 = Probes issues
|
||||||
|
* 1 = Probes not issued
|
||||||
|
* [ 1: 1] Disable Read Doubleword probe
|
||||||
|
* 0 = Probes issued
|
||||||
|
* 1 = Probes not issued
|
||||||
|
* [ 2: 2] Disable write byte probes
|
||||||
|
* 0 = Probes issued
|
||||||
|
* 1 = Probes not issued
|
||||||
|
* [ 3: 3] Disable Write Doubleword Probes
|
||||||
|
* 0 = Probes issued
|
||||||
|
* 1 = Probes not issued.
|
||||||
|
* [10:10] Disable Fill Probe
|
||||||
|
* 0 = Probes issued for cache fills
|
||||||
|
* 1 = Probes not issued for cache fills.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
print_debug("Disabling read/write/fill probes for UP... ");
|
||||||
|
|
||||||
|
val=pci_read_config32(NODE_HT(0), 0x68);
|
||||||
|
val |= 0x0000040f;
|
||||||
|
pci_write_config32(NODE_HT(0), 0x68, val);
|
||||||
|
|
||||||
|
print_debug("done.\r\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void enable_routing(u8 node)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
/* HT Initialization Control Register
|
||||||
|
* F0:0x6C
|
||||||
|
* [ 0: 0] Routing Table Disable
|
||||||
|
* 0 = Packets are routed according to routing tables
|
||||||
|
* 1 = Packets are routed according to the default link field
|
||||||
|
* [ 1: 1] Request Disable (BSP should clear this)
|
||||||
|
* 0 = Request packets may be generated
|
||||||
|
* 1 = Request packets may not be generated.
|
||||||
|
* [ 3: 2] Default Link (Read-only)
|
||||||
|
* 00 = LDT0
|
||||||
|
* 01 = LDT1
|
||||||
|
* 10 = LDT2
|
||||||
|
* 11 = CPU on same node
|
||||||
|
* [ 4: 4] Cold Reset
|
||||||
|
* - Scratch bit cleared by a cold reset
|
||||||
|
* [ 5: 5] BIOS Reset Detect
|
||||||
|
* - Scratch bit cleared by a cold reset
|
||||||
|
* [ 6: 6] INIT Detect
|
||||||
|
* - Scratch bit cleared by a warm or cold reset not by an INIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Enable routing table for BSP */
|
||||||
|
print_debug("Enabling routing table for node ");
|
||||||
|
print_debug_hex32(node);
|
||||||
|
|
||||||
|
val=pci_read_config32(NODE_HT(node), 0x6c);
|
||||||
|
val |= (1 << 6) | (1 << 5) | (1 << 4);
|
||||||
|
#if 0
|
||||||
|
val &= ~((1<<1)|(1<<0));
|
||||||
|
#else
|
||||||
|
/* Don't enable requests here as the indicated processor starts booting */
|
||||||
|
val &= ~(1<<0);
|
||||||
|
#endif
|
||||||
|
pci_write_config32(NODE_HT(node), 0x6c, val);
|
||||||
|
|
||||||
|
print_debug(" done.\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MAX_CPUS > 1
|
||||||
|
|
||||||
|
static void rename_temp_node(u8 node)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
print_debug("Renaming current temp node to ");
|
||||||
|
print_debug_hex32(node);
|
||||||
|
|
||||||
|
val=pci_read_config32(NODE_HT(7), 0x60);
|
||||||
|
val &= (~7); /* clear low bits. */
|
||||||
|
val |= node; /* new node */
|
||||||
|
pci_write_config32(NODE_HT(7), 0x60, val);
|
||||||
|
|
||||||
|
print_debug(" done.\r\n");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool check_connection(u8 src, u8 dest, u8 link)
|
||||||
|
{
|
||||||
|
/* this function does 2 things:
|
||||||
|
* 1) detect whether the coherent HT link is connected
|
||||||
|
* 2) verify that the coherent hypertransport link
|
||||||
|
* is established and actually working by reading the
|
||||||
|
* remote node's vendor/device id
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define UP 0x00
|
||||||
|
#define ACROSS 0x20
|
||||||
|
#define DOWN 0x40
|
||||||
|
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
/* 1) */
|
||||||
|
val=pci_read_config32(NODE_HT(src), 0x98+link);
|
||||||
|
if ( (val&0x17) != 0x03)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* 2) */
|
||||||
|
val=pci_read_config32(NODE_HT(dest),0);
|
||||||
|
if(val != 0x11001022)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int generate_row(u8 node, u8 row, u8 maxnodes)
|
||||||
|
{
|
||||||
|
/* Routing Table Node i
|
||||||
|
*
|
||||||
|
* F0: 0x40, 0x44, 0x48, 0x4c, 0x50, 0x54, 0x58, 0x5c
|
||||||
|
* i: 0, 1, 2, 3, 4, 5, 6, 7
|
||||||
|
*
|
||||||
|
* [ 0: 3] Request Route
|
||||||
|
* [0] Route to this node
|
||||||
|
* [1] Route to Link 0
|
||||||
|
* [2] Route to Link 1
|
||||||
|
* [3] Route to Link 2
|
||||||
|
* [11: 8] Response Route
|
||||||
|
* [0] Route to this node
|
||||||
|
* [1] Route to Link 0
|
||||||
|
* [2] Route to Link 1
|
||||||
|
* [3] Route to Link 2
|
||||||
|
* [19:16] Broadcast route
|
||||||
|
* [0] Route to this node
|
||||||
|
* [1] Route to Link 0
|
||||||
|
* [2] Route to Link 1
|
||||||
|
* [3] Route to Link 2
|
||||||
|
*/
|
||||||
|
|
||||||
|
u32 ret=DEFAULT;
|
||||||
|
|
||||||
|
static const unsigned int rows_2p[2][2] = {
|
||||||
|
{ 0x00030101, 0x00010404 },
|
||||||
|
{ 0x00010404, 0x00030101 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned int rows_4p[4][4] = {
|
||||||
|
{ 0x00070101, 0x00010404, 0x00050202, 0x00010402 },
|
||||||
|
{ 0x00010808, 0x000b0101, 0x00010802, 0x00090202 },
|
||||||
|
{ 0x00090202, 0x00010802, 0x000b0101, 0x00010808 },
|
||||||
|
{ 0x00010402, 0x00050202, 0x00010404, 0x00070101 }
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!(node>=maxnodes || row>=maxnodes)) {
|
||||||
|
if (maxnodes==2)
|
||||||
|
ret=rows_2p[node][row];
|
||||||
|
if (maxnodes==4)
|
||||||
|
ret=rows_4p[node][row];
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printk_spew("generating entry n=%d, r=%d, max=%d - row=%x\n",
|
||||||
|
node,row,maxnodes,ret);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fill_row(u8 node, u8 row, u32 value)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
print_debug("fill_row: pci_write_config32(");
|
||||||
|
print_debug_hex32(NODE_HT(node));
|
||||||
|
print_debug_char(',');
|
||||||
|
print_debug_hex32(0x40 + (row << 2));
|
||||||
|
print_debug_char(',');
|
||||||
|
print_debug_hex32(value);
|
||||||
|
print_debug(")\r\n");
|
||||||
|
#endif
|
||||||
|
pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setup_row(u8 source, u8 dest, u8 cpus)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
printk_spew("setting up link from node %d to %d (%d cpus)\r\n",
|
||||||
|
source, dest, cpus);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fill_row(source,dest,generate_row(source,dest,cpus));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setup_temp_row(u8 source, u8 dest, u8 cpus)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
printk_spew("setting up temp. link from node %d to %d (%d cpus)\r\n",
|
||||||
|
source, dest, cpus);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fill_row(source,7,generate_temp_row(source,dest,cpus));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setup_node(u8 node, u8 cpus)
|
||||||
|
{
|
||||||
|
u8 row;
|
||||||
|
for(row=0; row<cpus; row++)
|
||||||
|
setup_row(node, row, cpus);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setup_remote_row(u8 source, u8 dest, u8 cpus)
|
||||||
|
{
|
||||||
|
fill_row(7, dest, generate_row(source, dest, cpus));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setup_remote_node(u8 node, u8 cpus)
|
||||||
|
{
|
||||||
|
static const uint8_t pci_reg[] = {
|
||||||
|
0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c,
|
||||||
|
0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
|
||||||
|
0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
|
||||||
|
0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
|
||||||
|
0xc4, 0xcc, 0xd4, 0xdc,
|
||||||
|
0xc0, 0xc8, 0xd0, 0xd8,
|
||||||
|
0xe0, 0xe4, 0xe8, 0xec,
|
||||||
|
};
|
||||||
|
uint8_t row;
|
||||||
|
int i;
|
||||||
|
#if 1
|
||||||
|
print_debug("setup_remote_node\r\n");
|
||||||
|
#endif
|
||||||
|
for(row=0; row<cpus; row++)
|
||||||
|
setup_remote_row(node, row, cpus);
|
||||||
|
|
||||||
|
/* copy the default resource map from node 0 */
|
||||||
|
for(i = 0; i < sizeof(pci_reg)/sizeof(pci_reg[0]); i++) {
|
||||||
|
uint32_t value;
|
||||||
|
uint8_t reg;
|
||||||
|
reg = pci_reg[i];
|
||||||
|
print_debug("copying reg: ");
|
||||||
|
print_debug_hex8(reg);
|
||||||
|
print_debug("\r\n");
|
||||||
|
value = pci_read_config32(NODE_MP(0), reg);
|
||||||
|
pci_write_config32(NODE_MP(7), reg, value);
|
||||||
|
|
||||||
|
}
|
||||||
|
#if 1
|
||||||
|
print_debug("setup_remote_done\r\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MAX_CPUS > 2
|
||||||
|
static void setup_temp_node(u8 node, u8 cpus)
|
||||||
|
{
|
||||||
|
u8 row;
|
||||||
|
for(row=0; row<cpus; row++)
|
||||||
|
fill_row(7,row,generate_row(node,row,cpus));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static u8 setup_uniprocessor(void)
|
||||||
|
{
|
||||||
|
print_debug("Enabling UP settings\r\n");
|
||||||
|
disable_probes();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MAX_CPUS > 1
|
||||||
|
static u8 setup_smp(void)
|
||||||
|
{
|
||||||
|
u8 cpus=2;
|
||||||
|
|
||||||
|
print_debug("Enabling SMP settings\r\n");
|
||||||
|
|
||||||
|
setup_row(0,0,cpus);
|
||||||
|
/* Setup and check a temporary connection to node 1 */
|
||||||
|
setup_temp_row(0,1,cpus);
|
||||||
|
|
||||||
|
if (!check_connection(0, 7, ACROSS)) { // Link: ACROSS
|
||||||
|
print_debug("No connection to Node 1.\r\n");
|
||||||
|
clear_temp_row(0); /* delete temp connection */
|
||||||
|
setup_uniprocessor(); /* and get up working */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We found 2 nodes so far */
|
||||||
|
setup_node(0, cpus); /* Node 1 is there. Setup Node 0 correctly */
|
||||||
|
setup_remote_node(1, cpus); /* Setup the routes on the remote node */
|
||||||
|
enable_routing(1); /* Enable routing on Node 1 */
|
||||||
|
rename_temp_node(1); /* Rename Node 7 to Node 1 */
|
||||||
|
|
||||||
|
clear_temp_row(0); /* delete temporary connection */
|
||||||
|
|
||||||
|
#if MAX_CPUS > 2
|
||||||
|
cpus=4;
|
||||||
|
|
||||||
|
/* Setup and check temporary connection from Node 0 to Node 2 */
|
||||||
|
setup_temp_row(0,2,cpus);
|
||||||
|
|
||||||
|
if (!check_connection(0, 7, UP)) { // Link: UP
|
||||||
|
print_debug("No connection to Node 2.\r\n");
|
||||||
|
clear_temp_row(0); /* delete temp connection */
|
||||||
|
// detect_mp_capability(2); /* and get 2p working */
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We found 3 nodes so far. Now setup a temporary
|
||||||
|
* connection from node 0 to node 3 via node 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
setup_temp_row(0,1,cpus); /* temp. link between nodes 0 and 1 */
|
||||||
|
setup_temp_row(1,3,cpus); /* temp. link between nodes 1 and 3 */
|
||||||
|
|
||||||
|
if (!check_connection(0, 7, UP)) { // Link: UP
|
||||||
|
print_debug("No connection to Node 3.\r\n");
|
||||||
|
clear_temp_row(0); /* delete temp connection */
|
||||||
|
clear_temp_row(1); /* delete temp connection */
|
||||||
|
//detect_mp_capability(2); /* and get 2p working */
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We found 4 nodes so far. Now setup all nodes for 4p */
|
||||||
|
|
||||||
|
setup_node(0, cpus); /* The first 2 nodes are configured */
|
||||||
|
setup_node(1, cpus); /* already. Just configure them for 4p */
|
||||||
|
|
||||||
|
setup_temp_row(0,2,cpus);
|
||||||
|
setup_temp_node(2,cpus);
|
||||||
|
enable_routing(7);
|
||||||
|
rename_temp_node(2);
|
||||||
|
|
||||||
|
setup_temp_row(0,1,cpus);
|
||||||
|
setup_temp_row(1,3,cpus);
|
||||||
|
setup_temp_node(3,cpus);
|
||||||
|
enable_routing(3);
|
||||||
|
rename_temp_node(3);
|
||||||
|
|
||||||
|
clear_temp_row(0);
|
||||||
|
clear_temp_row(1);
|
||||||
|
clear_temp_row(2);
|
||||||
|
clear_temp_row(3);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
print_debug_hex32(cpus);
|
||||||
|
print_debug(" nodes initialized.\r\n");
|
||||||
|
return cpus;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MAX_CPUS > 1
|
||||||
|
static unsigned detect_mp_capabilities(unsigned cpus)
|
||||||
|
{
|
||||||
|
unsigned node, row, mask;
|
||||||
|
bool mp_cap=TRUE;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
print_debug("detect_mp_capabilities: ");
|
||||||
|
print_debug_hex32(cpus);
|
||||||
|
print_debug("\r\n");
|
||||||
|
#endif
|
||||||
|
if (cpus>2)
|
||||||
|
mask=0x04; /* BigMPCap */
|
||||||
|
else
|
||||||
|
mask=0x02; /* MPCap */
|
||||||
|
|
||||||
|
for (node=0; node<cpus; node++) {
|
||||||
|
if (!(pci_read_config32(NODE_MC(node), 0xe8) & mask))
|
||||||
|
mp_cap=FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mp_cap)
|
||||||
|
return cpus;
|
||||||
|
|
||||||
|
/* one of our cpus is not mp capable */
|
||||||
|
|
||||||
|
print_debug("One of the CPUs is not MP capable. Going back to UP\r\n");
|
||||||
|
|
||||||
|
for (node=cpus; node>0; node--)
|
||||||
|
for (row=cpus; row>0; row--)
|
||||||
|
fill_row(NODE_HT(node-1), row-1, DEFAULT);
|
||||||
|
|
||||||
|
return setup_uniprocessor();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* this is a shrunken cpuid. */
|
||||||
|
|
||||||
|
static unsigned int cpuid(unsigned int op)
|
||||||
|
{
|
||||||
|
unsigned int ret;
|
||||||
|
|
||||||
|
asm volatile ( "cpuid" : "=a" (ret) : "a" (op));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void coherent_ht_finalize(unsigned cpus)
|
||||||
|
{
|
||||||
|
int node;
|
||||||
|
bool rev_a0;
|
||||||
|
|
||||||
|
/* set up cpu count and node count and enable Limit
|
||||||
|
* Config Space Range for all available CPUs.
|
||||||
|
* Also clear non coherent hypertransport bus range
|
||||||
|
* registers on Hammer A0 revision.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
print_debug("coherent_ht_finalize\r\n");
|
||||||
|
#endif
|
||||||
|
rev_a0=((cpuid(1)&0xffff)==0x0f10);
|
||||||
|
|
||||||
|
for (node=0; node<cpus; node++) {
|
||||||
|
u32 val;
|
||||||
|
val=pci_read_config32(NODE_HT(node), 0x60);
|
||||||
|
val &= 0x000F0070;
|
||||||
|
val |= ((cpus-1)<<16)|((cpus-1)<<4);
|
||||||
|
pci_write_config32(NODE_HT(node),0x60,val);
|
||||||
|
|
||||||
|
val=pci_read_config32(NODE_HT(node), 0x68);
|
||||||
|
val |= 0x00008000;
|
||||||
|
pci_write_config32(NODE_HT(node),0x68,val);
|
||||||
|
|
||||||
|
if (rev_a0) {
|
||||||
|
pci_write_config32(NODE_HT(node),0x94,0);
|
||||||
|
pci_write_config32(NODE_HT(node),0xb4,0);
|
||||||
|
pci_write_config32(NODE_HT(node),0xd4,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
print_debug("done\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setup_coherent_ht_domain(void)
|
||||||
|
{
|
||||||
|
unsigned cpus;
|
||||||
|
|
||||||
|
enable_bsp_routing();
|
||||||
|
|
||||||
|
#if MAX_CPUS == 1
|
||||||
|
cpus=setup_uniprocessor();
|
||||||
|
#else
|
||||||
|
cpus=setup_smp();
|
||||||
|
cpus=detect_mp_capabilities(cpus);
|
||||||
|
#endif
|
||||||
|
coherent_ht_finalize(cpus);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -1051,7 +1051,7 @@ static void set_dimm_size(const struct mem_controller *ctrl, struct dimm_size sz
|
||||||
uint32_t base0, base1, map;
|
uint32_t base0, base1, map;
|
||||||
uint32_t dch;
|
uint32_t dch;
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
print_debug("set_dimm_size: (");
|
print_debug("set_dimm_size: (");
|
||||||
print_debug_hex32(sz.side1);
|
print_debug_hex32(sz.side1);
|
||||||
print_debug_char(',');
|
print_debug_char(',');
|
||||||
|
@ -1133,6 +1133,11 @@ static void route_dram_accesses(const struct mem_controller *ctrl,
|
||||||
limit -= 0x00010000;
|
limit -= 0x00010000;
|
||||||
pci_write_config32(ctrl->f1, 0x44, limit | (0 << 7) | (link_id << 4) | (node_id << 0));
|
pci_write_config32(ctrl->f1, 0x44, limit | (0 << 7) | (link_id << 4) | (node_id << 0));
|
||||||
pci_write_config32(ctrl->f1, 0x40, (base_k << 2) | (0 << 8) | (1<<1) | (1<<0));
|
pci_write_config32(ctrl->f1, 0x40, (base_k << 2) | (0 << 8) | (1<<1) | (1<<0));
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
pci_write_config32(PCI_DEV(0, 0x19, 1), 0x44, limit | (0 << 7) | (link_id << 4) | (node_id << 0));
|
||||||
|
pci_write_config32(PCI_DEV(0, 0x19, 1), 0x40, (base_k << 2) | (0 << 8) | (1<<1) | (1<<0));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_top_mem(unsigned tom_k)
|
static void set_top_mem(unsigned tom_k)
|
||||||
|
@ -1141,10 +1146,21 @@ static void set_top_mem(unsigned tom_k)
|
||||||
if (!tom_k) {
|
if (!tom_k) {
|
||||||
die("No memory");
|
die("No memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now set top of memory */
|
/* Now set top of memory */
|
||||||
msr_t msr;
|
msr_t msr;
|
||||||
msr.lo = (tom_k & 0x003fffff) << 10;
|
msr.lo = (tom_k & 0x003fffff) << 10;
|
||||||
msr.hi = (tom_k & 0xffc00000) >> 22;
|
msr.hi = (tom_k & 0xffc00000) >> 22;
|
||||||
|
wrmsr(TOP_MEM2, msr);
|
||||||
|
|
||||||
|
/* Leave a 64M hole between TOP_MEM and TOP_MEM2
|
||||||
|
* so I can see my rom chip and other I/O devices.
|
||||||
|
*/
|
||||||
|
if (tom_k >= 0x003f0000) {
|
||||||
|
tom_k = 0x3f0000;
|
||||||
|
}
|
||||||
|
msr.lo = (tom_k & 0x003fffff) << 10;
|
||||||
|
msr.hi = (tom_k & 0xffc00000) >> 22;
|
||||||
wrmsr(TOP_MEM, msr);
|
wrmsr(TOP_MEM, msr);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -1219,7 +1235,7 @@ static void order_dimms(const struct mem_controller *ctrl)
|
||||||
|
|
||||||
}
|
}
|
||||||
tom_k = (tom & ~0xff000000) << 15;
|
tom_k = (tom & ~0xff000000) << 15;
|
||||||
#if 1
|
#if 0
|
||||||
print_debug("tom: ");
|
print_debug("tom: ");
|
||||||
print_debug_hex32(tom);
|
print_debug_hex32(tom);
|
||||||
print_debug(" tom_k: ");
|
print_debug(" tom_k: ");
|
||||||
|
@ -1277,7 +1293,7 @@ static void spd_handle_unbuffered_dimms(const struct mem_controller *ctrl)
|
||||||
dcl |= DCL_UnBufDimm;
|
dcl |= DCL_UnBufDimm;
|
||||||
}
|
}
|
||||||
pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
|
pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
|
||||||
#if 1
|
#if 0
|
||||||
if (is_registered(ctrl)) {
|
if (is_registered(ctrl)) {
|
||||||
print_debug("Registered\r\n");
|
print_debug("Registered\r\n");
|
||||||
} else {
|
} else {
|
||||||
|
@ -1450,7 +1466,7 @@ static const struct mem_param *spd_set_memclk(const struct mem_controller *ctrl)
|
||||||
min_cycle_time = min_cycle_times[(value >> NBCAP_MEMCLK_SHIFT) & NBCAP_MEMCLK_MASK];
|
min_cycle_time = min_cycle_times[(value >> NBCAP_MEMCLK_SHIFT) & NBCAP_MEMCLK_MASK];
|
||||||
min_latency = 2;
|
min_latency = 2;
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
print_debug("min_cycle_time: ");
|
print_debug("min_cycle_time: ");
|
||||||
print_debug_hex8(min_cycle_time);
|
print_debug_hex8(min_cycle_time);
|
||||||
print_debug(" min_latency: ");
|
print_debug(" min_latency: ");
|
||||||
|
@ -1570,7 +1586,7 @@ static const struct mem_param *spd_set_memclk(const struct mem_controller *ctrl)
|
||||||
dimm_err:
|
dimm_err:
|
||||||
disable_dimm(ctrl, i);
|
disable_dimm(ctrl, i);
|
||||||
}
|
}
|
||||||
#if 1
|
#if 0
|
||||||
print_debug("min_cycle_time: ");
|
print_debug("min_cycle_time: ");
|
||||||
print_debug_hex8(min_cycle_time);
|
print_debug_hex8(min_cycle_time);
|
||||||
print_debug(" min_latency: ");
|
print_debug(" min_latency: ");
|
||||||
|
@ -1746,7 +1762,7 @@ static int update_dimm_Trp(const struct mem_controller *ctrl, const struct mem_p
|
||||||
#else
|
#else
|
||||||
clocks = (value + ((param->divisor & 0xff) << 1) - 1)/((param->divisor & 0xff) << 1);
|
clocks = (value + ((param->divisor & 0xff) << 1) - 1)/((param->divisor & 0xff) << 1);
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 0
|
||||||
print_debug("Trp: ");
|
print_debug("Trp: ");
|
||||||
print_debug_hex8(clocks);
|
print_debug_hex8(clocks);
|
||||||
print_debug(" spd value: ");
|
print_debug(" spd value: ");
|
||||||
|
@ -2172,7 +2188,7 @@ static void sdram_enable(const struct mem_controller *ctrl)
|
||||||
|
|
||||||
#warning "FIXME set the ECC type to perform"
|
#warning "FIXME set the ECC type to perform"
|
||||||
#warning "FIXME initialize the scrub registers"
|
#warning "FIXME initialize the scrub registers"
|
||||||
#if 1
|
#if 0
|
||||||
if (dcl & DCL_DimmEccEn) {
|
if (dcl & DCL_DimmEccEn) {
|
||||||
print_debug("ECC enabled\r\n");
|
print_debug("ECC enabled\r\n");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue