from issue 53: don't set TOM2 if 4G less mem installed, opt for init_ecc

git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2144 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Yinghai Lu 2005-12-14 20:16:49 +00:00
parent 6f63c0297c
commit 30576601f6
3 changed files with 75 additions and 50 deletions

View File

@ -175,6 +175,47 @@ static void set_init_ecc_mtrrs(void)
enable_cache();
}
static inline void clear_2M_ram(unsigned long basek, struct mtrr_state *mtrr_state)
{
unsigned long limitk;
unsigned long size;
void *addr;
/* Report every 64M */
if ((basek % (64*1024)) == 0) {
/* Restore the normal state */
map_2M_page(0);
restore_mtrr_state(mtrr_state);
enable_lapic();
/* Print a status message */
printk_debug("%c", (basek >= TOLM_KB)?'+':'-');
/* Return to the initialization state */
set_init_ecc_mtrrs();
disable_lapic();
}
limitk = (basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1);
#if 0
/* couldn't happen, memory must on 2M boundary */
if(limitk>endk) {
limitk = enk;
}
#endif
size = (limitk - basek) << 10;
addr = map_2M_page(basek >> 11);
if (addr == MAPPING_ERROR) {
printk_err("Cannot map page: %x\n", basek >> 11);
return;
}
/* clear memory 2M (limitk - basek) */
addr = (void *)(((uint32_t)addr) | ((basek & 0x7ff) << 10));
clear_memory(addr, size);
}
static void init_ecc_memory(unsigned node_id)
{
@ -182,6 +223,7 @@ static void init_ecc_memory(unsigned node_id)
unsigned long hole_startk = 0;
unsigned long basek;
struct mtrr_state mtrr_state;
device_t f1_dev, f2_dev, f3_dev;
int enable_scrubbing;
uint32_t dcl;
@ -242,6 +284,7 @@ static void init_ecc_memory(unsigned node_id)
if (begink < CONFIG_LB_MEM_TOPK) {
begink = CONFIG_LB_MEM_TOPK;
}
printk_debug("Clearing memory %uK - %uK: ", begink, endk);
/* Save the normal state */
@ -252,51 +295,29 @@ static void init_ecc_memory(unsigned node_id)
disable_lapic();
/* Walk through 2M chunks and zero them */
for(basek = begink; basek < endk;
basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1)))
{
unsigned long limitk;
unsigned long size;
void *addr;
#if K8_HW_MEM_HOLE_SIZEK != 0
if ( hole_startk != 0 ) {
if ((basek >= hole_startk) && (basek < 4*1024*1024)) continue;
}
/* here hole_startk can not be equal to begink, never. Also hole_startk is in 2M boundary, 64M? */
if ( (hole_startk != 0) && ((begink < hole_startk) && (endk>(4*1024*1024)))) {
for(basek = begink; basek < hole_startk;
basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1)))
{
clear_2M_ram(basek, &mtrr_state);
}
for(basek = 4*1024*1024; basek < endk;
basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1)))
{
clear_2M_ram(basek, &mtrr_state);
}
}
else
#endif
/* Report every 64M */
if ((basek % (64*1024)) == 0) {
/* Restore the normal state */
map_2M_page(0);
restore_mtrr_state(&mtrr_state);
enable_lapic();
/* Print a status message */
printk_debug("%c", (basek >= TOLM_KB)?'+':'-');
/* Return to the initialization state */
set_init_ecc_mtrrs();
disable_lapic();
}
limitk = (basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1);
if (limitk > endk) {
limitk = endk;
}
size = (limitk - basek) << 10;
addr = map_2M_page(basek >> 11);
if (addr == MAPPING_ERROR) {
printk_err("Cannot map page: %x\n", basek >> 11);
continue;
}
/* clear memory 2M (limitk - basek) */
addr = (void *)(((uint32_t)addr) | ((basek & 0x7ff) << 10));
clear_memory(addr, size);
for(basek = begink; basek < endk;
basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1)))
{
clear_2M_ram(basek, &mtrr_state);
}
/* Restore the normal state */
map_2M_page(0);
restore_mtrr_state(&mtrr_state);

View File

@ -149,10 +149,12 @@ void amd_setup_mtrrs(void)
msr.lo = state.mmio_basek << 10;
wrmsr(TOP_MEM, msr);
/* Setup TOP_MEM2 */
msr.hi = state.tomk >> 22;
msr.lo = state.tomk << 10;
wrmsr(TOP_MEM2, msr);
if(state.tomk>(4*1024*1024)) {
/* Setup TOP_MEM2 */
msr.hi = state.tomk >> 22;
msr.lo = state.tomk << 10;
wrmsr(TOP_MEM2, msr);
}
/* zero the IORR's before we enable to prevent
* undefined side effects.

View File

@ -882,9 +882,11 @@ static void set_top_mem(unsigned tom_k, unsigned hole_startk)
/* Now set top of memory */
msr_t msr;
msr.lo = (tom_k & 0x003fffff) << 10;
msr.hi = (tom_k & 0xffc00000) >> 22;
wrmsr(TOP_MEM2, msr);
if(tom_k>(4*1024*1024)) {
msr.lo = (tom_k & 0x003fffff) << 10;
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.