2005.02 yhlu add E0 memory hole support
*/
-#include <cpu/x86/mem.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/mtrr.h>
#include <stdlib.h>
+#include <reset.h>
#include "raminit.h"
#include "amdk8.h"
+#if CONFIG_HAVE_OPTION_TABLE
+#include "option_table.h"
+#endif
#if (CONFIG_RAMTOP & (CONFIG_RAMTOP -1)) != 0
# error "CONFIG_RAMTOP must be a power of 2"
#endif
-#ifndef QRANK_DIMM_SUPPORT
-#define QRANK_DIMM_SUPPORT 0
-#endif
-
-#if defined (__GNUC__)
-static void hard_reset(void);
-#endif
-
-static void setup_resource_map(const unsigned int *register_values, int max)
+void setup_resource_map(const unsigned int *register_values, int max)
{
int i;
-// printk_debug("setting up resource map....");
+// printk(BIOS_DEBUG, "setting up resource map....");
for (i = 0; i < max; i += 3) {
device_t dev;
unsigned where;
reg |= register_values[i+2];
pci_write_config32(dev, where, reg);
}
-// printk_debug("done.\n");
+// printk(BIOS_DEBUG, "done.\n");
}
static int controller_present(const struct mem_controller *ctrl)
return pci_read_config32(ctrl->f0, 0) == 0x11001022;
}
-#if RAMINIT_SYSINFO==1
+#if CONFIG_RAMINIT_SYSINFO
static void sdram_set_registers(const struct mem_controller *ctrl, struct sys_info *sysinfo)
#else
static void sdram_set_registers(const struct mem_controller *ctrl)
int max;
if (!controller_present(ctrl)) {
-// printk_debug("No memory controller present\n");
+// printk(BIOS_DEBUG, "No memory controller present\n");
return;
}
- printk_spew("setting up CPU%02x northbridge registers\n", ctrl->node_id);
+ printk(BIOS_SPEW, "setting up CPU%02x northbridge registers\n", ctrl->node_id);
max = ARRAY_SIZE(register_values);
for (i = 0; i < max; i += 3) {
device_t dev;
reg |= register_values[i+2];
pci_write_config32(dev, where, reg);
}
- printk_spew("done.\n");
+ printk(BIOS_SPEW, "done.\n");
}
static void hw_enable_ecc(const struct mem_controller *ctrl)
if (nbcap & NBCAP_ECC) {
dcl |= DCL_DimmEccEn;
}
- if (CONFIG_HAVE_OPTION_TABLE &&
- read_option(CMOS_VSTART_ECC_memory, CMOS_VLEN_ECC_memory, 1) == 0) {
+ if (read_option(CMOS_VSTART_ECC_memory, CMOS_VLEN_ECC_memory, 1) == 0) {
dcl &= ~DCL_DimmEccEn;
}
pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
static int is_opteron(const struct mem_controller *ctrl)
{
- /* Test to see if I am an Opteron.
- * FIXME Socket 939 based Athlon64 have dual channel capability,
- * too, so we need a better test for Opterons
+ /* Test to see if I am an Opteron. Socket 939 based Athlon64
+ * have dual channel capability, too, so we need a better test
+ * for Opterons.
+ * However, all code uses is_opteron() to find out whether to
+ * use dual channel, so if we really check for opteron here, we
+ * need to fix up all code using this function, too.
*/
-#warning "FIXME: Implement a better test for Opterons"
uint32_t nbcap;
nbcap = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
return !!(nbcap & NBCAP_128Bit);
unsigned long side2;
unsigned long rows;
unsigned long col;
-#if QRANK_DIMM_SUPPORT == 1
+#if CONFIG_QRANK_DIMM_SUPPORT
unsigned long rank;
#endif
};
sz.side2 = 0;
sz.rows = 0;
sz.col = 0;
-#if QRANK_DIMM_SUPPORT == 1
+#if CONFIG_QRANK_DIMM_SUPPORT
sz.rank = 0;
#endif
if ((value != 2) && (value != 4 )) {
goto val_err;
}
-#if QRANK_DIMM_SUPPORT == 1
+#if CONFIG_QRANK_DIMM_SUPPORT
sz.rank = value;
#endif
sz.side2 = 0;
sz.rows = 0;
sz.col = 0;
-#if QRANK_DIMM_SUPPORT == 1
+#if CONFIG_QRANK_DIMM_SUPPORT
sz.rank = 0;
#endif
out:
/* Set the appropriate DIMM base address register */
pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+0)<<2), base0);
pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+1)<<2), base1);
-#if QRANK_DIMM_SUPPORT == 1
+#if CONFIG_QRANK_DIMM_SUPPORT
if (sz.rank == 4) {
pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+4)<<2), base0);
pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+5)<<2), base1);
if (base0) {
dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
dch |= DCH_MEMCLK_EN0 << index;
-#if QRANK_DIMM_SUPPORT == 1
+#if CONFIG_QRANK_DIMM_SUPPORT
if (sz.rank == 4) {
dch |= DCH_MEMCLK_EN0 << (index + 2);
}
map = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP);
map &= ~(0xf << (index * 4));
-#if QRANK_DIMM_SUPPORT == 1
+#if CONFIG_QRANK_DIMM_SUPPORT
if (sz.rank == 4) {
map &= ~(0xf << ( (index + 2) * 4));
}
if (sz.side1 >= (25 +3)) {
if (is_cpu_pre_d0()) {
map |= (sz.side1 - (25 + 3)) << (index *4);
-#if QRANK_DIMM_SUPPORT == 1
+#if CONFIG_QRANK_DIMM_SUPPORT
if (sz.rank == 4) {
map |= (sz.side1 - (25 + 3)) << ( (index + 2) * 4);
}
}
else {
map |= cs_map_aa[(sz.rows - 12) * 5 + (sz.col - 8) ] << (index*4);
-#if QRANK_DIMM_SUPPORT == 1
+#if CONFIG_QRANK_DIMM_SUPPORT
if (sz.rank == 4) {
map |= cs_map_aa[(sz.rows - 12) * 5 + (sz.col - 8) ] << ( (index + 2) * 4);
}
}
/* Report the amount of memory. */
- printk_debug("RAM end at 0x%08x kB\n", tom_k);
+ printk(BIOS_DEBUG, "RAM end at 0x%08x kB\n", tom_k);
/* Now set top of memory */
msr_t msr;
if (tom_k > (4*1024*1024)) {
- printk_spew("Handling memory mapped above 4 GB\n");
- printk_spew("Upper RAM end at 0x%08x kB\n", tom_k);
+ printk(BIOS_SPEW, "Handling memory mapped above 4 GB\n");
+ printk(BIOS_SPEW, "Upper RAM end at 0x%08x kB\n", tom_k);
msr.lo = (tom_k & 0x003fffff) << 10;
msr.hi = (tom_k & 0xffc00000) >> 22;
wrmsr(TOP_MEM2, msr);
- printk_spew("Correcting memory amount mapped below 4 GB\n");
+ printk(BIOS_SPEW, "Correcting memory amount mapped below 4 GB\n");
}
/* Leave a 64M hole between TOP_MEM and TOP_MEM2
} else
#endif
tom_k = 0x3f0000;
- printk_spew("Adjusting lower RAM end\n");
+ printk(BIOS_SPEW, "Adjusting lower RAM end\n");
}
- printk_spew("Lower RAM end at 0x%08x kB\n", tom_k);
+ printk(BIOS_SPEW, "Lower RAM end at 0x%08x kB\n", tom_k);
msr.lo = (tom_k & 0x003fffff) << 10;
msr.hi = (tom_k & 0xffc00000) >> 22;
wrmsr(TOP_MEM, msr);
if (is_dual_channel(ctrl)) {
/* Also we run out of address mask bits if we try and interleave 8 4GB dimms */
if ((bits == 3) && (common_size == (1 << (32 - 3)))) {
-// printk_debug("8 4GB chip selects cannot be interleaved\n");
+// printk(BIOS_DEBUG, "8 4GB chip selects cannot be interleaved\n");
return 0;
}
csbase_inc <<=1;
csbase_inc = 1 << csbase_low_d0_shift[common_cs_mode];
if (is_dual_channel(ctrl)) {
if ( (bits==3) && (common_cs_mode > 8)) {
-// printk_debug("8 cs_mode>8 chip selects cannot be interleaved\n");
+// printk(BIOS_DEBUG, "8 cs_mode>8 chip selects cannot be interleaved\n");
return 0;
}
csbase_inc <<=1;
csbase += csbase_inc;
}
- printk_spew("Interleaved\n");
+ printk(BIOS_SPEW, "Interleaved\n");
/* Return the memory size in K */
return common_size << (15 + bits);
return (tom & ~0xff000000) << 15;
}
-unsigned long memory_end_k(const struct mem_controller *ctrl, int max_node_id)
+static unsigned long memory_end_k(const struct mem_controller *ctrl, int max_node_id)
{
unsigned node_id;
unsigned end_k;
{
unsigned long tom_k, base_k;
- if ((!CONFIG_HAVE_OPTION_TABLE) ||
- read_option(CMOS_VSTART_interleave_chip_selects, CMOS_VLEN_interleave_chip_selects, 1) != 0) {
+ if (read_option(CMOS_VSTART_interleave_chip_selects, CMOS_VLEN_interleave_chip_selects, 1) != 0) {
tom_k = interleave_chip_selects(ctrl);
} else {
- printk_debug("Interleaving disabled\n");
+ printk(BIOS_DEBUG, "Interleaving disabled\n");
tom_k = 0;
}
static long disable_dimm(const struct mem_controller *ctrl, unsigned index, long dimm_mask)
{
- printk_debug("disabling dimm %02x\n", index);
+ printk(BIOS_DEBUG, "disabling dimm %02x\n", index);
pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+0)<<2), 0);
pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+1)<<2), 0);
dimm_mask &= ~(1 << index);
pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
if (is_registered(ctrl)) {
- printk_spew("Registered\n");
+ printk(BIOS_SPEW, "Registered\n");
} else {
- printk_spew("Unbuffered\n");
+ printk(BIOS_SPEW, "Unbuffered\n");
}
return dimm_mask;
}
}
}
- printk_spew("Enabling dual channel memory\n");
+ printk(BIOS_SPEW, "Enabling dual channel memory\n");
uint32_t dcl;
dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
dcl &= ~DCL_32ByteEn;
if (!param->cycle_time) {
die("min_cycle_time to low");
}
- printk_spew("%s\n", param->name);
+ printk(BIOS_SPEW, "%s\n", param->name);
return param;
}
min_cycle_time = min_cycle_times[(value >> NBCAP_MEMCLK_SHIFT) & NBCAP_MEMCLK_MASK];
bios_cycle_time = min_cycle_times[
read_option(CMOS_VSTART_max_mem_clock, CMOS_VLEN_max_mem_clock, 0)];
- if (CONFIG_HAVE_OPTION_TABLE && bios_cycle_time > min_cycle_time) {
+ if (bios_cycle_time > min_cycle_time) {
min_cycle_time = bios_cycle_time;
}
min_latency = 2;
}
#if 0
//down speed for full load 4 rank support
-#if QRANK_DIMM_SUPPORT
+#if CONFIG_QRANK_DIMM_SUPPORT
if (dimm_mask == (3|(3<<DIMM_SOCKETS)) ) {
int ranks = 4;
for (i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
{
uint32_t dcl;
int value;
-#if QRANK_DIMM_SUPPORT == 1
+#if CONFIG_QRANK_DIMM_SUPPORT
int rank;
#endif
int dimm;
return -1;
}
-#if QRANK_DIMM_SUPPORT == 1
+#if CONFIG_QRANK_DIMM_SUPPORT
rank = spd_read_byte(ctrl->channel0[i], 5); /* number of physical banks */
if (rank < 0) {
return -1;
#endif
dimm = 1<<(DCL_x4DIMM_SHIFT+i);
-#if QRANK_DIMM_SUPPORT == 1
+#if CONFIG_QRANK_DIMM_SUPPORT
if (rank==4) {
dimm |= 1<<(DCL_x4DIMM_SHIFT+i+2);
}
return dimm_mask;
}
-#if RAMINIT_SYSINFO==1
+#if CONFIG_RAMINIT_SYSINFO
static void sdram_set_spd_registers(const struct mem_controller *ctrl, struct sys_info *sysinfo)
#else
static void sdram_set_spd_registers(const struct mem_controller *ctrl)
long dimm_mask;
#if 1
if (!controller_present(ctrl)) {
-// printk_debug("No memory controller present\n");
+// printk(BIOS_DEBUG, "No memory controller present\n");
return;
}
#endif
activate_spd_rom(ctrl);
dimm_mask = spd_detect_dimms(ctrl);
if (!(dimm_mask & ((1 << DIMM_SOCKETS) - 1))) {
- printk_debug("No memory for this cpu\n");
+ printk(BIOS_DEBUG, "No memory for this cpu\n");
return;
}
dimm_mask = spd_enable_2channels(ctrl, dimm_mask);
return;
hw_spd_err:
/* Unrecoverable error reading SPD data */
- printk_err("SPD error - reset\n");
+ printk(BIOS_ERR, "SPD error - reset\n");
hard_reset();
return;
}
hole_startk = 4*1024*1024 - CONFIG_HW_MEM_HOLE_SIZEK;
- printk_spew("Handling memory hole at 0x%08x (default)\n", hole_startk);
+ printk(BIOS_SPEW, "Handling memory hole at 0x%08x (default)\n", hole_startk);
#if CONFIG_HW_MEM_HOLE_SIZE_AUTO_INC == 1
/* We need to double check if hole_startk is valid.
* If it is equal to the dram base address in K (base_k),
basek_pri = base_k;
}
- printk_spew("Handling memory hole at 0x%08x (adjusted)\n", hole_startk);
+ printk(BIOS_SPEW, "Handling memory hole at 0x%08x (adjusted)\n", hole_startk);
#endif
/* Find node number that needs the memory hole configured */
for (i=0; i<controllers; i++) {
#endif
#define TIMEOUT_LOOPS 300000
-#if RAMINIT_SYSINFO == 1
+#if CONFIG_RAMINIT_SYSINFO
static void sdram_enable(int controllers, const struct mem_controller *ctrl, struct sys_info *sysinfo)
#else
static void sdram_enable(int controllers, const struct mem_controller *ctrl)
dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
if (dcl & DCL_DimmEccEn) {
uint32_t mnc;
- printk_spew("ECC enabled\n");
+ printk(BIOS_SPEW, "ECC enabled\n");
mnc = pci_read_config32(ctrl[i].f3, MCA_NB_CONFIG);
mnc |= MNC_ECC_EN;
if (dcl & DCL_128BitEn) {
continue;
}
- printk_debug("Initializing memory: ");
+ printk(BIOS_DEBUG, "Initializing memory: ");
int loops = 0;
do {
dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
loops++;
if ((loops & 1023) == 0) {
- printk_debug(".");
+ printk(BIOS_DEBUG, ".");
}
} while(((dcl & DCL_DramInit) != 0) && (loops < TIMEOUT_LOOPS));
if (loops >= TIMEOUT_LOOPS) {
- printk_debug(" failed\n");
+ printk(BIOS_DEBUG, " failed\n");
continue;
}
} while(((dcl & DCL_MemClrStatus) == 0) || ((dcl & DCL_DramEnable) == 0) );
}
- printk_debug(" done\n");
+ printk(BIOS_DEBUG, " done\n");
}
#if CONFIG_HW_MEM_HOLE_SIZEK != 0
{
}
-static void fill_mem_ctrl(int controllers, struct mem_controller *ctrl_a,
+void fill_mem_ctrl(int controllers, struct mem_controller *ctrl_a,
const uint16_t *spd_addr)
{
int i;