Attached patch fixes IDE compatibility mode (so FILO works),
and RAM initialization, so the DIMM on the second slot works.
SPD is not used by this patch, we have to figure out how to
type MA mapping by SPD (see the comment in the code).
Maybe I will work on SPD-based RAM timing.
earlymtrr.c should go to src/cpu/p6 so the XIP works.
The change in src/cpu/p6/mtrr.c just reverse the change made by
Eric for K8..
--
Takeshi
? src/cpu/p6/earlymtrr.c
? targets/epia
? targets/via/epia/epia
Index: src/cpu/p6/mtrr.c
===================================================================
RCS file: /cvsroot/freebios/freebios2/src/cpu/p6/mtrr.c,v
retrieving revision 1.5
diff -u -r1.5 mtrr.c
--- src/cpu/p6/mtrr.c 11 Oct 2003 06:20:17 -0000 1.5
+++ src/cpu/p6/mtrr.c 19 Oct 2003 19:24:03 -0000
@@ -92,7 +92,7 @@
base.lo = basek << 10;
if (sizek < 4*1024*1024) {
- mask.hi = 0x0FF;
+ mask.hi = 0x0F;
mask.lo = ~((sizek << 10) -1);
}
else {
Index: src/mainboard/via/epia/Config.lb
===================================================================
RCS file: /cvsroot/freebios/freebios2/src/mainboard/via/epia/Config.lb,v
retrieving revision 1.5
diff -u -r1.5 Config.lb
--- src/mainboard/via/epia/Config.lb 1 Oct 2003 23:18:14 -0000 1.5
+++ src/mainboard/via/epia/Config.lb 19 Oct 2003 19:24:03 -0000
@@ -53,8 +53,8 @@
##
## Clean up the motherboard id strings
##
-option MAINBOARD_PART_NUMBER="HDAMA"
-option MAINBOARD_VENDOR="ARIMA"
+option MAINBOARD_PART_NUMBER="EPIA"
+option MAINBOARD_VENDOR="VIA"
###
### LinuxBIOS layout values
@@ -137,7 +137,7 @@
makerule ./failover.inc
depends "./failover.E ./romcc"
- action "./romcc -O -o failover.inc --label-prefix=failover ./failover.E"
+ action "./romcc -O2 -mcpu=c3 -o failover.inc --label-prefix=failover
./failover.E"
end
makerule ./auto.E
@@ -146,7 +146,7 @@
end
makerule ./auto.inc
depends "./auto.E ./romcc"
- action "./romcc -O ./auto.E > auto.inc"
+ action "./romcc -O2 -mcpu=c3 -o auto.inc ./auto.E"
end
##
@@ -220,7 +220,7 @@
# pci 0:11.6
# pci 0:12.0
register "enable_usb" = "0"
- register "enable_native_ide" = "1"
+ register "enable_native_ide" = "0"
register "enable_com_ports" = "1"
register "enable_keyboard" = "0"
register "enable_nvram" = "1"
@@ -236,4 +236,3 @@
##
mainboardinit pc80/serial.inc
mainboardinit arch/i386/lib/console.inc
-
Index: src/mainboard/via/epia/auto.c
===================================================================
RCS file: /cvsroot/freebios/freebios2/src/mainboard/via/epia/auto.c,v
retrieving revision 1.12
diff -u -r1.12 auto.c
--- src/mainboard/via/epia/auto.c 3 Oct 2003 02:53:01 -0000 1.12
+++ src/mainboard/via/epia/auto.c 19 Oct 2003 19:24:03 -0000
@@ -11,6 +11,7 @@
#include "arch/i386/lib/console.c"
#include "ram/ramtest.c"
#include "northbridge/via/vt8601/raminit.h"
+#include "cpu/p6/earlymtrr.c"
/*
*/
void udelay(int usecs)
@@ -77,7 +78,7 @@
/* we do this here as in V2, we can not yet do raw operations
* to pci!
*/
- dev++; /* ICKY */
+ dev += 0x100; /* ICKY */
pci_write_config8(dev, 0x42, 0);
}
@@ -99,10 +100,10 @@
outb(5, 0x80);
enable_vt8231_serial();
- enable_mainboard_devices();
uart_init();
console_init();
+ enable_mainboard_devices();
enable_smbus();
enable_shadow_ram();
/*
@@ -134,4 +135,5 @@
ram_check(check_addrs[i].lo, check_addrs[i].hi);
}
#endif
+ early_mtrr_init();
}
Index: src/northbridge/via/vt8601/raminit.c
===================================================================
RCS file: /cvsroot/freebios/freebios2/src/northbridge/via/vt8601/raminit.c,v
retrieving revision 1.11
diff -u -r1.11 raminit.c
--- src/northbridge/via/vt8601/raminit.c 3 Oct 2003 02:53:01 -0000 1.11
+++ src/northbridge/via/vt8601/raminit.c 19 Oct 2003 19:24:03 -0000
@@ -121,7 +121,7 @@
uint8_t c, r;
print_err("vt8601 init starting\n");
- north = pci_locate_device(PCI_ID(0x1106, 0x8601), 0);
+ //north = pci_locate_device(PCI_ID(0x1106, 0x8601), 0);
north = 0;
print_err_hex32(north);
print_err(" is the north\n");
@@ -279,6 +279,117 @@
*/
}
+static unsigned long find_size(unsigned long base)
+{
+ unsigned long i;
+ unsigned long maximum;
+ volatile long *p;
+
+ /* First, see if there is any RAM. */
+ p = (long *) base;
+ *p = 0x12345678;
+ p = (long *) (base + 8);
+ *p = 0x87654321;
+ p = (long *) base;
+ if (*p != 0x12345678)
+ return 0; /* No memory */
+
+ maximum = (0xffUL << 23) - base;
+
+ /* Write to addresses with only one address bit on,
+ * in increasing order from address 8 (64-bit bus),
+ * then read address zero to see if it gets wrap-around.
+ * This way we can detect missing address bit due to incorrect
+ * MA mapping, or the size of bank when MA mapping is correct. */
+
+ for (i = 8; i < maximum; i <<= 1) {
+ p = (long *) (base + i);
+ *p = 0x55555555;
+ p = (long *) base;
+ if (*p == 0x55555555)
+ return i & ~0x7fffff; /* 8MB align */
+ }
+ return maximum;
+}
+
+static void set_ma_mapping(device_t north, int bank, int type)
+{
+ unsigned char reg, val;
+ int shift;
+
+ reg = 0x58 + bank/4;
+ if (bank%4 >= 2)
+ shift = 0;
+ else
+ shift = 4;
+
+ val = pci_read_config8(north, reg);
+ val &= ~(0xf << shift);
+ val |= type << shift;
+ pci_write_config8(north, reg, val);
+}
+
+static void find_ma_type(device_t north)
+{
+ unsigned long memtop, highest, size;
+ int bank, i;
+ static const unsigned char ma_table[] = { 0, 8, 0xe };
+ unsigned char ma_tmp, val;
+
+ /* Temporary setting for probing - maximum possible RAM on bank 0 */
+ pci_write_config8(north, 0x5A, 0xFF);
+ pci_write_config8(north, 0x5B, 0xFF);
+ pci_write_config8(north, 0x5C, 0xFF);
+ pci_write_config8(north, 0x5D, 0xFF);
+ pci_write_config8(north, 0x5E, 0xFF);
+ pci_write_config8(north, 0x5F, 0xFF);
+ pci_write_config8(north, 0x56, 0xFF);
+ pci_write_config8(north, 0x57, 0xFF);
+
+ memtop = 0;
+ for (bank = 0; bank < 6; bank++) {
+ print_debug("Bank");
+ print_debug_hex8(bank);
+ print_debug(": ");
+ if (bank & 1) {
+ /* We don't change MA mapping of this bank
+ * since it is shared with the previous bank.
+ * Most possibly this is the other side of a
+ * double-sided DIMM. */
+ size = find_size(memtop);
+ } else {
+ /* Try MA mapping types and find the one which gives
+ * highest address without wrap-around.
+ * It should be the correct mapping for the DIMM,
+ * and the returned address is the size of the DIMM. */
+ highest = 0;
+ ma_tmp = 0;
+ for (i = 0;
+ i < sizeof(ma_table) / sizeof(ma_table[0]);
+ i++) {
+ set_ma_mapping(north, bank, ma_table[i]);
+ size = find_size(memtop);
+ if (size > highest) {
+ highest = size;
+ ma_tmp = ma_table[i];
+ }
+ }
+ print_debug("MA=");
+ print_debug_hex8(ma_tmp);
+ print_debug(": ");
+ set_ma_mapping(north, bank, ma_tmp);
+ size = highest;
+ }
+ print_debug_hex32(size);
+ print_debug(" bytes\r\n");
+ memtop += size;
+ pci_write_config8(north, 0x5a + bank, memtop >> 23);
+ }
+ /* As well as 6 bank registers above, it seems we have to fill
+ * these 2 registers. */
+ pci_write_config8(north, 0x56, memtop >> 23);
+ pci_write_config8(north, 0x57, memtop >> 23);
+}
static void sdram_enable(int controllers, const struct mem_controller *ctrl)
{
unsigned char i;
@@ -358,94 +469,17 @@
print_err("enable multi-page open\r\n");
// enable multi-page open
pci_write_config8(north,0x6B, 0x0d);
-
- /* Begin auto-detection
- * Find the first bank with DIMM equipped. */
-
- /* Maximum possible memory in bank 0, none in other banks.
- * Starting from bank 0, we fill 0 in these registers
- * until memory is found. */
- pci_write_config8(north,0x5A, 0xff);
- pci_write_config8(north,0x5B, 0xff);
- pci_write_config8(north,0x5C, 0xff);
- pci_write_config8(north,0x5D, 0xff);
- pci_write_config8(north,0x5E, 0xff);
- pci_write_config8(north,0x5F, 0xff);
- pci_write_config8(north,0x56, 0xff);
- pci_write_config8(north,0x57, 0xff);
- dumpnorth(north);
- print_err("MA\r\n");
- for(c = 0; c < 8; c++) {
- /* Write different values to 0 and 8, then read from 0.
- * If values of address 0 match, we have something there. */
- print_err("write to 0\r\n");
- *(volatile unsigned long *) 0 = 0x12345678;
-
- /* LEAVE THIS HERE. IT IS ESSENTIAL. OTHERWISE BUFFERING
- * WILL FOOL YOU!
- */
- print_err("write to 8\r\n");
- *(volatile unsigned long *) 8 = 0x87654321;
-
- if (*(volatile unsigned long *) 0 != 0x12345678) {
- print_err("no memory in this bank\r\n");
- /* No memory in this bank. Tell it to the bridge. */
- pci_write_config8(north,ramregs[c], 0);
- }
- /* found something */
- {
- uint8_t best = 0;
-
- /* Detect MA mapping type of the bank. */
-
- for(r = 0; r < 3; r++) {
- volatile unsigned long esi = 0;
- volatile unsigned long eax = 0;
- pci_write_config8(north,0x58, raminit_ma_reg_table[r]);
-
- * (volatile unsigned long *) eax = 0;
- print_err(" done write to eax\r\n");
- // Write to addresses with only one address bit
- // on, from 0x80000000 to 0x00000008 (lower 3 bits
- // are ignored, assuming 64-bit bus). Then what
- // is read at address 0 is the value written to
- // the lowest address where it gets
- // wrap-around. That address is either the size of
- // the bank, or a missing bit due to incorrect MA
- // mapping.
- eax = 0x80000000;
- while (eax != 4) {
- * (volatile unsigned long *) eax = eax;
- //print_err_hex32(eax);
- outb(eax&0xff, 0x80);
- eax >>= 1;
- }
- print_err(" done read to eax\r\n");
- eax = * (unsigned long *)0;
- /* oh boy ... what is this.
- movl 0, %eax
- cmpl %eax, %esi
- jnc 3f
- */
- print_err("eax and esi: ");
- print_err_hex32(eax); print_err(" ");
- print_err_hex32(esi); print_err("\r\n");
-
- if (eax > esi) { /* ??*/
-
- // This is the current best MA mapping.
- // Save the address and its MA mapping value.
- best = r;
- esi = eax;
- }
- }
-
- pci_write_config8(north,0x58, raminit_ma_reg_table[best]);
- print_err("enabled first bank of ram ... ma is ");
- print_err_hex8(pci_read_config8(north, 0x58));
- print_err("\r\n");
- }
- }
+
+ /* Provisional MA mapping type detection by probing.
+ * This should be removed in favor of SPD, but be here until
+ * we figure out how to set MA type by SPD. */
+ find_ma_type(north);
+
+ /* The above routine has already set the RAM sizes, so SPD is not
+ * really needed for now.
+ * The following code will come to life again when the MA typing
+ * is done by SPD. */
+#if 0
base = 0;
/* runs out of variable space. */
/* this is unrolled and constants used as much as possible to help
@@ -476,6 +510,7 @@
base = do_module_size(0xa0, base);
base = do_module_size(0xa0, base);
base = do_module_size(0xa0, base);*/
+#endif
print_err("vt8601 done\n");
dumpnorth(north);
udelay(1000);
Index: src/southbridge/via/vt8231/vt8231.c
===================================================================
RCS file: /cvsroot/freebios/freebios2/src/southbridge/via/vt8231/vt8231.c,v
retrieving revision 1.7
diff -u -r1.7 vt8231.c
--- src/southbridge/via/vt8231/vt8231.c 11 Oct 2003 06:20:22 -0000 1.7
+++ src/southbridge/via/vt8231/vt8231.c 19 Oct 2003 19:24:03 -0000
@@ -335,11 +335,11 @@
//
// IDE setup
//
- if (conf->enable_native_ide) {
+ if (!conf->enable_native_ide) {
// Run the IDE controller in 'compatiblity mode - i.e. don't use PCI
// interrupts. Using PCI ints confuses linux for some reason.
- printk_info("%s: enabling native IDE addresses\n", __FUNCTION__);
+ printk_info("%s: enabling compatibility IDE addresses\n",
__FUNCTION__);
enables = pci_read_config8(dev1, 0x42);
printk_debug("enables in reg 0x42 0x%x\n", enables);
enables &= ~0xc0; // compatability mode
@@ -442,7 +442,6 @@
break;
case CONF_PASS_PRE_BOOT:
- pci_routing_fixup();
dump_south();
break;
Index: targets/via/epia/Config.lb
===================================================================
RCS file: /cvsroot/freebios/freebios2/targets/via/epia/Config.lb,v
retrieving revision 1.7
diff -u -r1.7 Config.lb
--- targets/via/epia/Config.lb 2 Oct 2003 04:16:30 -0000 1.7
+++ targets/via/epia/Config.lb 19 Oct 2003 19:24:03 -0000
@@ -52,8 +52,8 @@
option CONFIG_CHIP_CONFIGURE=1
option CONFIG_KEYBOARD=1
-option MAXIMUM_CONSOLE_LOGLEVEL=10
-option DEFAULT_CONSOLE_LOGLEVEL=10
+option MAXIMUM_CONSOLE_LOGLEVEL=8
+option DEFAULT_CONSOLE_LOGLEVEL=8
option CONFIG_CONSOLE_SERIAL8250=1
option CPU_FIXUP=1
@@ -91,7 +91,8 @@
mainboard via/epia
# payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
# payload ../../../../tg3--ide_disk.zelf
- payload ../../../../../lnxieepro100.ebi
+# payload ../../../../../lnxieepro100.ebi
+ payload ../../../../../../filo/filo.elf
end
romimage "fallback"
@@ -101,7 +102,8 @@
mainboard via/epia
# payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
# payload ../../../../tg3--ide_disk.zelf
- payload ../../../../../lnxieepro100.ebi
+# payload ../../../../../lnxieepro100.ebi
+ payload ../../../../../../filo/filo.elf
end
buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback"
#include <cpu/p6/mtrr.h>
#include <cpu/p6/msr.h>
static inline unsigned long read_cr0(void)
{
unsigned long cr0;
asm volatile ("movl %%cr0, %0" : "=r" (cr0));
return cr0;
}
static inline void write_cr0(unsigned long cr0)
{
asm volatile ("movl %0, %%cr0" : : "r" (cr0));
}
/* the fixed and variable MTTRs are power-up with random values,
* clear them to MTRR_TYPE_UNCACHEABLE for safty.
*/
static void early_mtrr_init(void)
{
static const unsigned long mtrr_msrs[] = {
/* fixed mtrr */
0x250, 0x258, 0x259,
0x268, 0x269, 0x26A,
0x26B, 0x26C, 0x26D,
0x26E, 0x26F,
/* var mtrr */
0x200, 0x201, 0x202, 0x203,
0x204, 0x205, 0x206, 0x207,
0x208, 0x209, 0x20A, 0x20B,
0x20C, 0x20D, 0x20E, 0x20F,
/* NULL end of table */
0
};
msr_t msr;
const unsigned long *msr_addr;
unsigned long cr0;
/* Just to be sure, take all the steps to disable the cache.
* This may not be needed, but C3's may...
* Invalidate the cache */
asm volatile ("invd");
/* Disable the cache */
cr0 = read_cr0();
cr0 |= 0x40000000;
write_cr0(cr0);
/* Disable Variable MTRRs */
msr.hi = 0x00000000;
msr.lo = 0x00000000;
wrmsr(0x2ff, msr);
/* Invalidate the cache again */
asm volatile ("invd");
/* Inialize all of the relevant msrs to 0 */
msr.lo = 0;
msr.hi = 0;
for(msr_addr = mtrr_msrs; *msr_addr; msr_addr++) {
wrmsr(*msr_addr, msr);
}
/* Enable caching for 0 - 128MB using variable mtrr */
msr = rdmsr(0x200);
msr.hi &= 0xfffffff0;
msr.hi |= 0x00000000;
msr.lo &= 0x00000f00;
msr.lo |= 0x00000006;
wrmsr(0x200, msr);
msr = rdmsr(0x201);
msr.hi &= 0xfffffff0;
msr.hi |= 0x0000000f;
msr.lo &= 0x000007ff;
msr.lo |= 0xf0000800;
wrmsr(0x201, msr);
#if defined(XIP_ROM_SIZE) && defined(XIP_ROM_BASE)
/* enable write through caching so we can do execute in place
* on the flash rom.
*/
msr.hi = 0x00000000;
msr.lo = XIP_ROM_BASE | MTRR_TYPE_WRTHROUGH;
wrmsr(0x202, msr);
msr.hi = 0x0000000f;
msr.lo = ~(XIP_ROM_SIZE - 1) | 0x800;
wrmsr(0x203, msr);
#endif
/* Set the default memory type and enable fixed and variable MTRRs
*/
/* Enable Variable MTRRs */
msr.hi = 0x00000000;
msr.lo = 0x00000800;
wrmsr(0x2ff, msr);
/* Enable the cache */
cr0 = read_cr0();
cr0 &= 0x9fffffff;
write_cr0(cr0);
print_err("Enabled the cache\r\n");
}