summaryrefslogtreecommitdiff
path: root/util/romcc/tests
diff options
context:
space:
mode:
authorEric Biederman <ebiederm@xmission.com>2003-10-11 06:20:25 +0000
committerEric Biederman <ebiederm@xmission.com>2003-10-11 06:20:25 +0000
commit83b991afff40e12a8b6756af06a472842edb1a66 (patch)
treea441ff0d88afcb0a07cf22dc3653db3e07a05c98 /util/romcc/tests
parent080038bfbd8fdf08bac12476a3789495e6f705ca (diff)
downloadcoreboot-83b991afff40e12a8b6756af06a472842edb1a66.tar.xz
- O2, enums, and switch statements work in romcc
- Support for compiling romcc on non x86 platforms - new romc options -msse and -mmmx for specifying extra registers to use - Bug fixes to device the device disable/enable framework and an amd8111 implementation - Move the link specification to the chip specification instead of the path - Allow specifying devices with internal bridges. - Initial via epia support - Opteron errata fixes git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1200 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'util/romcc/tests')
-rw-r--r--util/romcc/tests/fail_test4.c14
-rw-r--r--util/romcc/tests/fail_test5.c14
-rw-r--r--util/romcc/tests/linux_console.h136
-rw-r--r--util/romcc/tests/linux_syscall.h7
-rw-r--r--util/romcc/tests/linux_test1.c8
-rw-r--r--util/romcc/tests/linux_test2.c673
-rw-r--r--util/romcc/tests/linux_test3.c28
-rw-r--r--util/romcc/tests/linux_test4.c46
-rw-r--r--util/romcc/tests/linux_test5.c359
-rw-r--r--util/romcc/tests/linux_test6.c17
-rw-r--r--util/romcc/tests/linux_test7.c35
-rw-r--r--util/romcc/tests/linuxi386_syscall.h299
-rw-r--r--util/romcc/tests/raminit_test6.c2800
-rw-r--r--util/romcc/tests/simple_test57.c5
-rw-r--r--util/romcc/tests/simple_test58.c9
-rw-r--r--util/romcc/tests/simple_test60.c2
-rw-r--r--util/romcc/tests/simple_test61.c26
-rw-r--r--util/romcc/tests/simple_test62.c7
-rw-r--r--util/romcc/tests/simple_test63.c8
-rw-r--r--util/romcc/tests/simple_test64.c12
-rw-r--r--util/romcc/tests/simple_test65.c10
-rw-r--r--util/romcc/tests/simple_test66.c25
-rw-r--r--util/romcc/tests/simple_test67.c24
-rw-r--r--util/romcc/tests/simple_test68.c21
24 files changed, 4584 insertions, 1 deletions
diff --git a/util/romcc/tests/fail_test4.c b/util/romcc/tests/fail_test4.c
new file mode 100644
index 0000000000..a2d3bece66
--- /dev/null
+++ b/util/romcc/tests/fail_test4.c
@@ -0,0 +1,14 @@
+static void main(void)
+{
+ static const int foo = 2;
+ switch(foo) {
+ case 1:
+ break;
+ case 2:
+ break;
+ case 1:
+ break;
+ default:
+ break;
+ }
+}
diff --git a/util/romcc/tests/fail_test5.c b/util/romcc/tests/fail_test5.c
new file mode 100644
index 0000000000..efa4e76d91
--- /dev/null
+++ b/util/romcc/tests/fail_test5.c
@@ -0,0 +1,14 @@
+static void main(void)
+{
+ static const int foo = 2;
+ switch(foo) {
+ case 1:
+ break;
+ default:
+ break;
+ case 2:
+ break;
+ default:
+ break;
+ }
+}
diff --git a/util/romcc/tests/linux_console.h b/util/romcc/tests/linux_console.h
new file mode 100644
index 0000000000..0837dfc577
--- /dev/null
+++ b/util/romcc/tests/linux_console.h
@@ -0,0 +1,136 @@
+#ifndef LINUX_CONSOLE_H
+#define LINUX_CONSOLE_H
+
+#include "linux_syscall.h"
+
+static const char *addr_of_char(unsigned char ch)
+{
+ static const char byte[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+ };
+ return byte + ch;
+}
+
+static void console_tx_byte(unsigned char ch)
+{
+ write(STDOUT_FILENO, addr_of_char(ch), 1);
+}
+
+static void console_tx_nibble(unsigned nibble)
+{
+ unsigned char digit;
+ digit = nibble + '0';
+ if (digit > '9') {
+ digit += 39;
+ }
+ console_tx_byte(digit);
+}
+
+static void console_tx_char(unsigned char byte)
+{
+ console_tx_byte(byte);
+}
+
+static void console_tx_hex8(unsigned char value)
+{
+ console_tx_nibble((value >> 4U) & 0x0fU);
+ console_tx_nibble(value & 0x0fU);
+}
+
+static void console_tx_hex16(unsigned short value)
+{
+ console_tx_nibble((value >> 12U) & 0x0FU);
+ console_tx_nibble((value >> 8U) & 0x0FU);
+ console_tx_nibble((value >> 4U) & 0x0FU);
+ console_tx_nibble(value & 0x0FU);
+}
+
+static void console_tx_hex32(unsigned short value)
+{
+ console_tx_nibble((value >> 28U) & 0x0FU);
+ console_tx_nibble((value >> 24U) & 0x0FU);
+ console_tx_nibble((value >> 20U) & 0x0FU);
+ console_tx_nibble((value >> 16U) & 0x0FU);
+ console_tx_nibble((value >> 12U) & 0x0FU);
+ console_tx_nibble((value >> 8U) & 0x0FU);
+ console_tx_nibble((value >> 4U) & 0x0FU);
+ console_tx_nibble(value & 0x0FU);
+}
+
+static void console_tx_string(const char *str)
+{
+ unsigned char ch;
+ while((ch = *str++) != '\0') {
+ console_tx_byte(ch);
+ }
+}
+
+static void print_emerg_char(unsigned char byte) { console_tx_char(byte); }
+static void print_emerg_hex8(unsigned char value) { console_tx_hex8(value); }
+static void print_emerg_hex16(unsigned short value){ console_tx_hex16(value); }
+static void print_emerg_hex32(unsigned int value) { console_tx_hex32(value); }
+static void print_emerg(const char *str) { console_tx_string(str); }
+
+static void print_warn_char(unsigned char byte) { console_tx_char(byte); }
+static void print_warn_hex8(unsigned char value) { console_tx_hex8(value); }
+static void print_warn_hex16(unsigned short value){ console_tx_hex16(value); }
+static void print_warn_hex32(unsigned int value) { console_tx_hex32(value); }
+static void print_warn(const char *str) { console_tx_string(str); }
+
+static void print_info_char(unsigned char byte) { console_tx_char(byte); }
+static void print_info_hex8(unsigned char value) { console_tx_hex8(value); }
+static void print_info_hex16(unsigned short value){ console_tx_hex16(value); }
+static void print_info_hex32(unsigned int value) { console_tx_hex32(value); }
+static void print_info(const char *str) { console_tx_string(str); }
+
+static void print_debug_char(unsigned char byte) { console_tx_char(byte); }
+static void print_debug_hex8(unsigned char value) { console_tx_hex8(value); }
+static void print_debug_hex16(unsigned short value){ console_tx_hex16(value); }
+static void print_debug_hex32(unsigned int value) { console_tx_hex32(value); }
+static void print_debug(const char *str) { console_tx_string(str); }
+
+static void print_spew_char(unsigned char byte) { console_tx_char(byte); }
+static void print_spew_hex8(unsigned char value) { console_tx_hex8(value); }
+static void print_spew_hex16(unsigned short value){ console_tx_hex16(value); }
+static void print_spew_hex32(unsigned int value) { console_tx_hex32(value); }
+static void print_spew(const char *str) { console_tx_string(str); }
+
+static void die(const char *str)
+{
+ print_emerg(str);
+ do {
+ asm volatile (" ");
+ } while(1);
+}
+#endif /* LINUX_CONSOLE_H */
diff --git a/util/romcc/tests/linux_syscall.h b/util/romcc/tests/linux_syscall.h
new file mode 100644
index 0000000000..487095f712
--- /dev/null
+++ b/util/romcc/tests/linux_syscall.h
@@ -0,0 +1,7 @@
+#ifndef LINUX_SYSCALL_H
+#define LINUX_SYSCALL_H
+
+/* When I support other platforms use #ifdefs here */
+#include "linuxi386_syscall.h"
+
+#endif /* LINUX_SYSCALL_H */
diff --git a/util/romcc/tests/linux_test1.c b/util/romcc/tests/linux_test1.c
new file mode 100644
index 0000000000..ee82148031
--- /dev/null
+++ b/util/romcc/tests/linux_test1.c
@@ -0,0 +1,8 @@
+#include "linux_syscall.h"
+
+static void main(void)
+{
+ static const char msg[] = "hello world\r\n";
+ write(STDOUT_FILENO, msg, sizeof(msg));
+ _exit(0);
+}
diff --git a/util/romcc/tests/linux_test2.c b/util/romcc/tests/linux_test2.c
new file mode 100644
index 0000000000..8f40fa0d47
--- /dev/null
+++ b/util/romcc/tests/linux_test2.c
@@ -0,0 +1,673 @@
+#include "linux_syscall.h"
+#include "linux_console.h"
+
+
+static void setup_coherent_ht_domain(void)
+{
+ static const unsigned int register_values[] = {
+#if 1
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x40) & 0xFF)), 0xfff0f0f0, 0x00010101,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x44) & 0xFF)), 0xfff0f0f0, 0x00010101,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x48) & 0xFF)), 0xfff0f0f0, 0x00010101,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x4c) & 0xFF)), 0xfff0f0f0, 0x00010101,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x50) & 0xFF)), 0xfff0f0f0, 0x00010101,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x54) & 0xFF)), 0xfff0f0f0, 0x00010101,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x58) & 0xFF)), 0xfff0f0f0, 0x00010101,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x5c) & 0xFF)), 0xfff0f0f0, 0x00010101,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x68) & 0xFF)), 0x00800000, 0x0f00840f,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x6C) & 0xFF)), 0xffffff8c, 0x00000000 | (1 << 6) |(1 << 5)| (1 << 4),
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x84) & 0xFF)), 0x00009c05, 0x11110020,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x88) & 0xFF)), 0xfffff0ff, 0x00000200,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x94) & 0xFF)), 0xff000000, 0x00ff0000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x44) & 0xFF)), 0x0000f8f8, 0x003f0000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x4C) & 0xFF)), 0x0000f8f8, 0x00000001,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x54) & 0xFF)), 0x0000f8f8, 0x00000002,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x5C) & 0xFF)), 0x0000f8f8, 0x00000003,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x64) & 0xFF)), 0x0000f8f8, 0x00000004,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x6C) & 0xFF)), 0x0000f8f8, 0x00000005,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x74) & 0xFF)), 0x0000f8f8, 0x00000006,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x7C) & 0xFF)), 0x0000f8f8, 0x00000007,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x40) & 0xFF)), 0x0000f8fc, 0x00000003,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x48) & 0xFF)), 0x0000f8fc, 0x00400000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x50) & 0xFF)), 0x0000f8fc, 0x00400000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x58) & 0xFF)), 0x0000f8fc, 0x00400000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x60) & 0xFF)), 0x0000f8fc, 0x00400000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x68) & 0xFF)), 0x0000f8fc, 0x00400000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x70) & 0xFF)), 0x0000f8fc, 0x00400000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x78) & 0xFF)), 0x0000f8fc, 0x00400000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x84) & 0xFF)), 0x00000048, 0x00e1ff00,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x8C) & 0xFF)), 0x00000048, 0x00dfff00,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x94) & 0xFF)), 0x00000048, 0x00e3ff00,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x9C) & 0xFF)), 0x00000048, 0x00000000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xA4) & 0xFF)), 0x00000048, 0x00000000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xAC) & 0xFF)), 0x00000048, 0x00000000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xB4) & 0xFF)), 0x00000048, 0x00000b00,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xBC) & 0xFF)), 0x00000048, 0x00fe0b00,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x80) & 0xFF)), 0x000000f0, 0x00e00003,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x88) & 0xFF)), 0x000000f0, 0x00d80003,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x90) & 0xFF)), 0x000000f0, 0x00e20003,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x98) & 0xFF)), 0x000000f0, 0x00000000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xA0) & 0xFF)), 0x000000f0, 0x00000000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xA8) & 0xFF)), 0x000000f0, 0x00000000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xB0) & 0xFF)), 0x000000f0, 0x00000a03,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xB8) & 0xFF)), 0x000000f0, 0x00400003,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xC4) & 0xFF)), 0xFE000FC8, 0x0000d000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xCC) & 0xFF)), 0xFE000FC8, 0x000ff000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xD4) & 0xFF)), 0xFE000FC8, 0x00000000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xDC) & 0xFF)), 0xFE000FC8, 0x00000000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xC0) & 0xFF)), 0xFE000FCC, 0x0000d003,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xC8) & 0xFF)), 0xFE000FCC, 0x00001013,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xD0) & 0xFF)), 0xFE000FCC, 0x00000000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xD8) & 0xFF)), 0xFE000FCC, 0x00000000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xE0) & 0xFF)), 0x0000FC88, 0xff000003,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xE4) & 0xFF)), 0x0000FC88, 0x00000000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xE8) & 0xFF)), 0x0000FC88, 0x00000000,
+ ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xEC) & 0xFF)), 0x0000FC88, 0x00000000,
+#else
+#define PCI_ADDR(BUS, DEV, FN, WHERE) ( \
+ (((BUS) & 0xFF) << 16) | \
+ (((DEV) & 0x1f) << 11) | \
+ (((FN) & 0x07) << 8) | \
+ ((WHERE) & 0xFF))
+
+ /* Routing Table Node i
+ * F0:0x40 i = 0,
+ * F0:0x44 i = 1,
+ * F0:0x48 i = 2,
+ * F0:0x4c i = 3,
+ * F0:0x50 i = 4,
+ * F0:0x54 i = 5,
+ * F0:0x58 i = 6,
+ * F0:0x5c i = 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
+ */
+ PCI_ADDR(0, 0x18, 0, 0x40), 0xfff0f0f0, 0x00010101,
+ PCI_ADDR(0, 0x18, 0, 0x44), 0xfff0f0f0, 0x00010101,
+ PCI_ADDR(0, 0x18, 0, 0x48), 0xfff0f0f0, 0x00010101,
+ PCI_ADDR(0, 0x18, 0, 0x4c), 0xfff0f0f0, 0x00010101,
+ PCI_ADDR(0, 0x18, 0, 0x50), 0xfff0f0f0, 0x00010101,
+ PCI_ADDR(0, 0x18, 0, 0x54), 0xfff0f0f0, 0x00010101,
+ PCI_ADDR(0, 0x18, 0, 0x58), 0xfff0f0f0, 0x00010101,
+ PCI_ADDR(0, 0x18, 0, 0x5c), 0xfff0f0f0, 0x00010101,
+
+ /* 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.
+ * [ 4: 4] Disable Memroy Controller Target Start
+ * 0 = TgtStart packets are generated
+ * 1 = TgtStart packets are not generated.
+ * [ 5: 5] CPU1 Enable
+ * 0 = Second CPU disabled or not present
+ * 1 = Second CPU enabled.
+ * [ 6: 6] CPU Request PassPW
+ * 0 = CPU requests do not pass posted writes
+ * 1 = CPU requests pass posted writes.
+ * [ 7: 7] CPU read Respons PassPW
+ * 0 = CPU Responses do not pass posted writes
+ * 1 = CPU responses pass posted writes.
+ * [ 8: 8] Disable Probe Memory Cancel
+ * 0 = Probes may generate MemCancels
+ * 1 = Probes may not generate MemCancels
+ * [ 9: 9] Disable Remote Probe Memory Cancel.
+ * 0 = Probes hitting dirty blocks generate memory cancel packets
+ * 1 = Only probed caches on the same node as the memory controller
+ * generate cancel packets.
+ * [10:10] Disable Fill Probe
+ * 0 = Probes issued for cache fills
+ * 1 = Probes not issued for cache fills.
+ * [11:11] Response PassPw
+ * 0 = Downstream response PassPW based on original request
+ * 1 = Downstream response PassPW set to 1
+ * [12:12] Change ISOC to Ordered
+ * 0 = Bit 1 of coherent HT RdSz/WrSz command used for iosynchronous prioritization
+ * 1 = Bit 1 of coherent HT RdSz/WrSz command used for ordering.
+ * [14:13] Buffer Release Priority select
+ * 00 = 64
+ * 01 = 16
+ * 10 = 8
+ * 11 = 2
+ * [15:15] Limit Coherent HT Configuration Space Range
+ * 0 = No coherent HT configuration space restrictions
+ * 1 = Limit coherent HT configuration space based on node count
+ * [16:16] Local Interrupt Conversion Enable.
+ * 0 = ExtInt/NMI interrups unaffected.
+ * 1 = ExtInt/NMI broadcat interrupts converted to LINT0/1
+ * [17:17] APIC Extended Broadcast Enable.
+ * 0 = APIC broadcast is 0F
+ * 1 = APIC broadcast is FF
+ * [18:18] APIC Extended ID Enable
+ * 0 = APIC ID is 4 bits.
+ * 1 = APIC ID is 8 bits.
+ * [19:19] APIC Extended Spurious Vector Enable
+ * 0 = Lower 4 bits of spurious vector are read-only 1111
+ * 1 = Lower 4 bits of spurious vecotr are writeable.
+ * [20:20] Sequence ID Source Node Enable
+ * 0 = Normal operation
+ * 1 = Keep SeqID on routed packets for debugging.
+ * [22:21] Downstream non-posted request limit
+ * 00 = No limit
+ * 01 = Limited to 1
+ * 10 = Limited to 4
+ * 11 = Limited to 8
+ * [23:23] RESERVED
+ * [25:24] Medium-Priority Bypass Count
+ * - Maximum # of times a medium priority access can pass a low
+ * priority access before Medium-Priority mode is disabled for one access.
+ * [27:26] High-Priority Bypass Count
+ * - Maximum # of times a high prioirty access can pass a medium or low
+ * priority access before High-prioirty mode is disabled for one access.
+ * [28:28] Enable High Priority CPU Reads
+ * 0 = Cpu reads are medium prioirty
+ * 1 = Cpu reads are high prioirty
+ * [29:29] Disable Low Priority Writes
+ * 0 = Non-isochronous writes are low priority
+ * 1 = Non-isochronous writes are medium prioirty
+ * [30:30] Disable High Priority Isochronous writes
+ * 0 = Isochronous writes are high priority
+ * 1 = Isochronous writes are medium priority
+ * [31:31] Disable Medium Priority Isochronous writes
+ * 0 = Isochronous writes are medium are high
+ * 1 = With bit 30 set makes Isochrouns writes low priority.
+ */
+ PCI_ADDR(0, 0x18, 0, 0x68), 0x00800000, 0x0f00840f,
+ /* 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
+ *
+ */
+ PCI_ADDR(0, 0x18, 0, 0x6C), 0xffffff8c, 0x00000000 | (1 << 6) |(1 << 5)| (1 << 4),
+ /* LDTi Capabilities Registers
+ * F0:0x80 i = 0,
+ * F0:0xA0 i = 1,
+ * F0:0xC0 i = 2,
+ */
+ /* LDTi Link Control Registrs
+ * F0:0x84 i = 0,
+ * F0:0xA4 i = 1,
+ * F0:0xC4 i = 2,
+ * [ 1: 1] CRC Flood Enable
+ * 0 = Do not generate sync packets on CRC error
+ * 1 = Generate sync packets on CRC error
+ * [ 2: 2] CRC Start Test (Read-Only)
+ * [ 3: 3] CRC Force Frame Error
+ * 0 = Do not generate bad CRC
+ * 1 = Generate bad CRC
+ * [ 4: 4] Link Failure
+ * 0 = No link failure detected
+ * 1 = Link failure detected
+ * [ 5: 5] Initialization Complete
+ * 0 = Initialization not complete
+ * 1 = Initialization complete
+ * [ 6: 6] Receiver off
+ * 0 = Recevier on
+ * 1 = Receiver off
+ * [ 7: 7] Transmitter Off
+ * 0 = Transmitter on
+ * 1 = Transmitter off
+ * [ 9: 8] CRC_Error
+ * 00 = No error
+ * [0] = 1 Error on byte lane 0
+ * [1] = 1 Error on byte lane 1
+ * [12:12] Isochrnous Enable (Read-Only)
+ * [13:13] HT Stop Tristate Enable
+ * 0 = Driven during an LDTSTOP_L
+ * 1 = Tristated during and LDTSTOP_L
+ * [14:14] Extended CTL Time
+ * 0 = CTL is asserted for 16 bit times during link initialization
+ * 1 = CTL is asserted for 50us during link initialization
+ * [18:16] Max Link Width In (Read-Only?)
+ * 000 = 8 bit link
+ * 001 = 16bit link
+ * [19:19] Doubleword Flow Control in (Read-Only)
+ * 0 = This link does not support doubleword flow control
+ * 1 = This link supports doubleword flow control
+ * [22:20] Max Link Width Out (Read-Only?)
+ * 000 = 8 bit link
+ * 001 = 16bit link
+ * [23:23] Doubleworld Flow Control out (Read-Only)
+ * 0 = This link does not support doubleword flow control
+ * 1 = This link supports doubleworkd flow control
+ * [26:24] Link Width In
+ * 000 = Use 8 bits
+ * 001 = Use 16 bits
+ * 010 = reserved
+ * 011 = Use 32 bits
+ * 100 = Use 2 bits
+ * 101 = Use 4 bits
+ * 110 = reserved
+ * 111 = Link physically not connected
+ * [27:27] Doubleword Flow Control In Enable
+ * 0 = Doubleword flow control disabled
+ * 1 = Doubleword flow control enabled (Not currently supported)
+ * [30:28] Link Width Out
+ * 000 = Use 8 bits
+ * 001 = Use 16 bits
+ * 010 = reserved
+ * 011 = Use 32 bits
+ * 100 = Use 2 bits
+ * 101 = Use 4 bits
+ * 110 = reserved
+ * 111 = Link physically not connected
+ * [31:31] Doubleworld Flow Control Out Enable
+ * 0 = Doubleworld flow control disabled
+ * 1 = Doubleword flow control enabled (Not currently supported)
+ */
+ PCI_ADDR(0, 0x18, 0, 0x84), 0x00009c05, 0x11110020,
+ /* LDTi Frequency/Revision Registers
+ * F0:0x88 i = 0,
+ * F0:0xA8 i = 1,
+ * F0:0xC8 i = 2,
+ * [ 4: 0] Minor Revision
+ * Contains the HT Minor revision
+ * [ 7: 5] Major Revision
+ * Contains the HT Major revision
+ * [11: 8] Link Frequency (Takes effect the next time the link is reconnected)
+ * 0000 = 200Mhz
+ * 0001 = reserved
+ * 0010 = 400Mhz
+ * 0011 = reserved
+ * 0100 = 600Mhz
+ * 0101 = 800Mhz
+ * 0110 = 1000Mhz
+ * 0111 = reserved
+ * 1000 = reserved
+ * 1001 = reserved
+ * 1010 = reserved
+ * 1011 = reserved
+ * 1100 = reserved
+ * 1101 = reserved
+ * 1110 = reserved
+ * 1111 = 100 Mhz
+ * [15:12] Error (Not currently Implemented)
+ * [31:16] Indicates the frequency capabilities of the link
+ * [16] = 1 encoding 0000 of freq supported
+ * [17] = 1 encoding 0001 of freq supported
+ * [18] = 1 encoding 0010 of freq supported
+ * [19] = 1 encoding 0011 of freq supported
+ * [20] = 1 encoding 0100 of freq supported
+ * [21] = 1 encoding 0101 of freq supported
+ * [22] = 1 encoding 0110 of freq supported
+ * [23] = 1 encoding 0111 of freq supported
+ * [24] = 1 encoding 1000 of freq supported
+ * [25] = 1 encoding 1001 of freq supported
+ * [26] = 1 encoding 1010 of freq supported
+ * [27] = 1 encoding 1011 of freq supported
+ * [28] = 1 encoding 1100 of freq supported
+ * [29] = 1 encoding 1101 of freq supported
+ * [30] = 1 encoding 1110 of freq supported
+ * [31] = 1 encoding 1111 of freq supported
+ */
+ PCI_ADDR(0, 0x18, 0, 0x88), 0xfffff0ff, 0x00000200,
+ /* LDTi Feature Capability
+ * F0:0x8C i = 0,
+ * F0:0xAC i = 1,
+ * F0:0xCC i = 2,
+ */
+ /* LDTi Buffer Count Registers
+ * F0:0x90 i = 0,
+ * F0:0xB0 i = 1,
+ * F0:0xD0 i = 2,
+ */
+ /* LDTi Bus Number Registers
+ * F0:0x94 i = 0,
+ * F0:0xB4 i = 1,
+ * F0:0xD4 i = 2,
+ * For NonCoherent HT specifies the bus number downstream (behind the host bridge)
+ * [ 0: 7] Primary Bus Number
+ * [15: 8] Secondary Bus Number
+ * [23:15] Subordiante Bus Number
+ * [31:24] reserved
+ */
+ PCI_ADDR(0, 0x18, 0, 0x94), 0xff000000, 0x00ff0000,
+ /* LDTi Type Registers
+ * F0:0x98 i = 0,
+ * F0:0xB8 i = 1,
+ * F0:0xD8 i = 2,
+ */
+ /* Careful set limit registers before base registers which contain the enables */
+ /* DRAM Limit i Registers
+ * F1:0x44 i = 0
+ * F1:0x4C i = 1
+ * F1:0x54 i = 2
+ * F1:0x5C i = 3
+ * F1:0x64 i = 4
+ * F1:0x6C i = 5
+ * F1:0x74 i = 6
+ * F1:0x7C i = 7
+ * [ 2: 0] Destination Node ID
+ * 000 = Node 0
+ * 001 = Node 1
+ * 010 = Node 2
+ * 011 = Node 3
+ * 100 = Node 4
+ * 101 = Node 5
+ * 110 = Node 6
+ * 111 = Node 7
+ * [ 7: 3] Reserved
+ * [10: 8] Interleave select
+ * specifies the values of A[14:12] to use with interleave enable.
+ * [15:11] Reserved
+ * [31:16] DRAM Limit Address i Bits 39-24
+ * This field defines the upper address bits of a 40 bit address
+ * that define the end of the DRAM region.
+ */
+#if MEMORY_1024MB
+ PCI_ADDR(0, 0x18, 1, 0x44), 0x0000f8f8, 0x003f0000,
+#endif
+#if MEMORY_512MB
+ PCI_ADDR(0, 0x18, 1, 0x44), 0x0000f8f8, 0x001f0000,
+#endif
+ PCI_ADDR(0, 0x18, 1, 0x4C), 0x0000f8f8, 0x00000001,
+ PCI_ADDR(0, 0x18, 1, 0x54), 0x0000f8f8, 0x00000002,
+ PCI_ADDR(0, 0x18, 1, 0x5C), 0x0000f8f8, 0x00000003,
+ PCI_ADDR(0, 0x18, 1, 0x64), 0x0000f8f8, 0x00000004,
+ PCI_ADDR(0, 0x18, 1, 0x6C), 0x0000f8f8, 0x00000005,
+ PCI_ADDR(0, 0x18, 1, 0x74), 0x0000f8f8, 0x00000006,
+ PCI_ADDR(0, 0x18, 1, 0x7C), 0x0000f8f8, 0x00000007,
+ /* DRAM Base i Registers
+ * F1:0x40 i = 0
+ * F1:0x48 i = 1
+ * F1:0x50 i = 2
+ * F1:0x58 i = 3
+ * F1:0x60 i = 4
+ * F1:0x68 i = 5
+ * F1:0x70 i = 6
+ * F1:0x78 i = 7
+ * [ 0: 0] Read Enable
+ * 0 = Reads Disabled
+ * 1 = Reads Enabled
+ * [ 1: 1] Write Enable
+ * 0 = Writes Disabled
+ * 1 = Writes Enabled
+ * [ 7: 2] Reserved
+ * [10: 8] Interleave Enable
+ * 000 = No interleave
+ * 001 = Interleave on A[12] (2 nodes)
+ * 010 = reserved
+ * 011 = Interleave on A[12] and A[14] (4 nodes)
+ * 100 = reserved
+ * 101 = reserved
+ * 110 = reserved
+ * 111 = Interleve on A[12] and A[13] and A[14] (8 nodes)
+ * [15:11] Reserved
+ * [13:16] DRAM Base Address i Bits 39-24
+ * This field defines the upper address bits of a 40-bit address
+ * that define the start of the DRAM region.
+ */
+ PCI_ADDR(0, 0x18, 1, 0x40), 0x0000f8fc, 0x00000003,
+#if MEMORY_1024MB
+ PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00400000,
+ PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00400000,
+ PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00400000,
+ PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00400000,
+ PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00400000,
+ PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00400000,
+ PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00400000,
+#endif
+#if MEMORY_512MB
+ PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00200000,
+ PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00200000,
+ PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00200000,
+ PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00200000,
+ PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00200000,
+ PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00200000,
+ PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00200000,
+#endif
+
+ /* Memory-Mapped I/O Limit i Registers
+ * F1:0x84 i = 0
+ * F1:0x8C i = 1
+ * F1:0x94 i = 2
+ * F1:0x9C i = 3
+ * F1:0xA4 i = 4
+ * F1:0xAC i = 5
+ * F1:0xB4 i = 6
+ * F1:0xBC i = 7
+ * [ 2: 0] Destination Node ID
+ * 000 = Node 0
+ * 001 = Node 1
+ * 010 = Node 2
+ * 011 = Node 3
+ * 100 = Node 4
+ * 101 = Node 5
+ * 110 = Node 6
+ * 111 = Node 7
+ * [ 3: 3] Reserved
+ * [ 5: 4] Destination Link ID
+ * 00 = Link 0
+ * 01 = Link 1
+ * 10 = Link 2
+ * 11 = Reserved
+ * [ 6: 6] Reserved
+ * [ 7: 7] Non-Posted
+ * 0 = CPU writes may be posted
+ * 1 = CPU writes must be non-posted
+ * [31: 8] Memory-Mapped I/O Limit Address i (39-16)
+ * This field defines the upp adddress bits of a 40-bit address that
+ * defines the end of a memory-mapped I/O region n
+ */
+ PCI_ADDR(0, 0x18, 1, 0x84), 0x00000048, 0x00e1ff00,
+ PCI_ADDR(0, 0x18, 1, 0x8C), 0x00000048, 0x00dfff00,
+ PCI_ADDR(0, 0x18, 1, 0x94), 0x00000048, 0x00e3ff00,
+ PCI_ADDR(0, 0x18, 1, 0x9C), 0x00000048, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xA4), 0x00000048, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xAC), 0x00000048, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xB4), 0x00000048, 0x00000b00,
+ PCI_ADDR(0, 0x18, 1, 0xBC), 0x00000048, 0x00fe0b00,
+
+ /* Memory-Mapped I/O Base i Registers
+ * F1:0x80 i = 0
+ * F1:0x88 i = 1
+ * F1:0x90 i = 2
+ * F1:0x98 i = 3
+ * F1:0xA0 i = 4
+ * F1:0xA8 i = 5
+ * F1:0xB0 i = 6
+ * F1:0xB8 i = 7
+ * [ 0: 0] Read Enable
+ * 0 = Reads disabled
+ * 1 = Reads Enabled
+ * [ 1: 1] Write Enable
+ * 0 = Writes disabled
+ * 1 = Writes Enabled
+ * [ 2: 2] Cpu Disable
+ * 0 = Cpu can use this I/O range
+ * 1 = Cpu requests do not use this I/O range
+ * [ 3: 3] Lock
+ * 0 = base/limit registers i are read/write
+ * 1 = base/limit registers i are read-only
+ * [ 7: 4] Reserved
+ * [31: 8] Memory-Mapped I/O Base Address i (39-16)
+ * This field defines the upper address bits of a 40bit address
+ * that defines the start of memory-mapped I/O region i
+ */
+ PCI_ADDR(0, 0x18, 1, 0x80), 0x000000f0, 0x00e00003,
+ PCI_ADDR(0, 0x18, 1, 0x88), 0x000000f0, 0x00d80003,
+ PCI_ADDR(0, 0x18, 1, 0x90), 0x000000f0, 0x00e20003,
+ PCI_ADDR(0, 0x18, 1, 0x98), 0x000000f0, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xA0), 0x000000f0, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xA8), 0x000000f0, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xB0), 0x000000f0, 0x00000a03,
+#if MEMORY_1024MB
+ PCI_ADDR(0, 0x18, 1, 0xB8), 0x000000f0, 0x00400003,
+#endif
+#if MEMORY_512MB
+ PCI_ADDR(0, 0x18, 1, 0xB8), 0x000000f0, 0x00200003,
+#endif
+
+ /* PCI I/O Limit i Registers
+ * F1:0xC4 i = 0
+ * F1:0xCC i = 1
+ * F1:0xD4 i = 2
+ * F1:0xDC i = 3
+ * [ 2: 0] Destination Node ID
+ * 000 = Node 0
+ * 001 = Node 1
+ * 010 = Node 2
+ * 011 = Node 3
+ * 100 = Node 4
+ * 101 = Node 5
+ * 110 = Node 6
+ * 111 = Node 7
+ * [ 3: 3] Reserved
+ * [ 5: 4] Destination Link ID
+ * 00 = Link 0
+ * 01 = Link 1
+ * 10 = Link 2
+ * 11 = reserved
+ * [11: 6] Reserved
+ * [24:12] PCI I/O Limit Address i
+ * This field defines the end of PCI I/O region n
+ * [31:25] Reserved
+ */
+ PCI_ADDR(0, 0x18, 1, 0xC4), 0xFE000FC8, 0x0000d000,
+ PCI_ADDR(0, 0x18, 1, 0xCC), 0xFE000FC8, 0x000ff000,
+ PCI_ADDR(0, 0x18, 1, 0xD4), 0xFE000FC8, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xDC), 0xFE000FC8, 0x00000000,
+
+ /* PCI I/O Base i Registers
+ * F1:0xC0 i = 0
+ * F1:0xC8 i = 1
+ * F1:0xD0 i = 2
+ * F1:0xD8 i = 3
+ * [ 0: 0] Read Enable
+ * 0 = Reads Disabled
+ * 1 = Reads Enabled
+ * [ 1: 1] Write Enable
+ * 0 = Writes Disabled
+ * 1 = Writes Enabled
+ * [ 3: 2] Reserved
+ * [ 4: 4] VGA Enable
+ * 0 = VGA matches Disabled
+ * 1 = matches all address < 64K and where A[9:0] is in the
+ * range 3B0-3BB or 3C0-3DF independen of the base & limit registers
+ * [ 5: 5] ISA Enable
+ * 0 = ISA matches Disabled
+ * 1 = Blocks address < 64K and in the last 768 bytes of eack 1K block
+ * from matching agains this base/limit pair
+ * [11: 6] Reserved
+ * [24:12] PCI I/O Base i
+ * This field defines the start of PCI I/O region n
+ * [31:25] Reserved
+ */
+ PCI_ADDR(0, 0x18, 1, 0xC0), 0xFE000FCC, 0x0000d003,
+ PCI_ADDR(0, 0x18, 1, 0xC8), 0xFE000FCC, 0x00001013,
+ PCI_ADDR(0, 0x18, 1, 0xD0), 0xFE000FCC, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xD8), 0xFE000FCC, 0x00000000,
+
+ /* Config Base and Limit i Registers
+ * F1:0xE0 i = 0
+ * F1:0xE4 i = 1
+ * F1:0xE8 i = 2
+ * F1:0xEC i = 3
+ * [ 0: 0] Read Enable
+ * 0 = Reads Disabled
+ * 1 = Reads Enabled
+ * [ 1: 1] Write Enable
+ * 0 = Writes Disabled
+ * 1 = Writes Enabled
+ * [ 2: 2] Device Number Compare Enable
+ * 0 = The ranges are based on bus number
+ * 1 = The ranges are ranges of devices on bus 0
+ * [ 3: 3] Reserved
+ * [ 6: 4] Destination Node
+ * 000 = Node 0
+ * 001 = Node 1
+ * 010 = Node 2
+ * 011 = Node 3
+ * 100 = Node 4
+ * 101 = Node 5
+ * 110 = Node 6
+ * 111 = Node 7
+ * [ 7: 7] Reserved
+ * [ 9: 8] Destination Link
+ * 00 = Link 0
+ * 01 = Link 1
+ * 10 = Link 2
+ * 11 - Reserved
+ * [15:10] Reserved
+ * [23:16] Bus Number Base i
+ * This field defines the lowest bus number in configuration region i
+ * [31:24] Bus Number Limit i
+ * This field defines the highest bus number in configuration regin i
+ */
+ PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0xff000003,
+ PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xEC), 0x0000FC88, 0x00000000,
+#endif
+ };
+ int i;
+ int max;
+ print_debug("setting up coherent ht domain....\r\n");
+ max = sizeof(register_values)/sizeof(register_values[0]);
+ for(i = 0; i < max; i += 3) {
+ unsigned long reg;
+#if 1
+ print_debug_hex32(register_values[i]);
+ print_debug(" <-");
+ print_debug_hex32(register_values[i+2]);
+ print_debug("\r\n");
+#endif
+#if 0
+ reg = pci_read_config32(register_values[i]);
+ reg &= register_values[i+1];
+ reg |= register_values[i+2] & ~register_values[i+1];
+ pci_write_config32(register_values[i], reg);
+#endif
+ }
+ print_debug("done.\r\n");
+}
+
+static void main(void)
+{
+ static const char msg[] = "hello world\r\n";
+#if 0
+ write(STDOUT_FILENO, msg, sizeof(msg));
+#endif
+#if 1
+ setup_coherent_ht_domain();
+#endif
+ _exit(0);
+}
diff --git a/util/romcc/tests/linux_test3.c b/util/romcc/tests/linux_test3.c
new file mode 100644
index 0000000000..97187ae5e6
--- /dev/null
+++ b/util/romcc/tests/linux_test3.c
@@ -0,0 +1,28 @@
+#include "linux_syscall.h"
+#include "linux_console.h"
+static void goto_test(void)
+{
+ int i;
+ print_debug("goto_test\n");
+
+ i = 0;
+ goto bottom;
+ {
+ top:
+ print_debug("i = ");
+ print_debug_hex8(i);
+ print_debug("\n");
+
+ i = i + 1;
+ }
+ bottom:
+ if (i < 10) {
+ goto top;
+ }
+}
+
+static void main(void)
+{
+ goto_test();
+ _exit(0);
+}
diff --git a/util/romcc/tests/linux_test4.c b/util/romcc/tests/linux_test4.c
new file mode 100644
index 0000000000..1f09918362
--- /dev/null
+++ b/util/romcc/tests/linux_test4.c
@@ -0,0 +1,46 @@
+#include "linux_syscall.h"
+#include "linux_console.h"
+
+struct socket_desc {
+ short up;
+ short down;
+ short across;
+};
+
+static void main(void)
+{
+ static const struct socket_desc cpu_socketsA[] = {
+ { .up = 2, .down = -1, .across = 1 }, /* Node 0 */
+ { .up = 3, .down = -1, .across = 0 }, /* Node 1 */
+ { .up = -1, .down = 0, .across = 3 }, /* Node 2 */
+ { .up = -1, .down = 1, .across = 2 } /* Node 3 */
+ };
+ static const struct socket_desc cpu_socketsB[4] = {
+ { 2, -1, 1 }, /* Node 0 */
+ { 3, -1, 0 }, /* Node 1 */
+ { -1, 0, 3 }, /* Node 2 */
+ { -1, 1, 2 } /* Node 3 */
+ };
+ int i;
+ print_debug("cpu_socketA\n");
+ for(i = 0; i < sizeof(cpu_socketsA)/sizeof(cpu_socketsA[0]); i++) {
+ print_debug(".up=");
+ print_debug_hex16(cpu_socketsA[i].up);
+ print_debug(" .down=");
+ print_debug_hex16(cpu_socketsA[i].down);
+ print_debug(" .across=");
+ print_debug_hex16(cpu_socketsA[i].across);
+ print_debug("\n");
+ }
+ print_debug("\ncpu_socketB\n");
+ for(i = 0; i < sizeof(cpu_socketsB)/sizeof(cpu_socketsB[0]); i++) {
+ print_debug(".up=");
+ print_debug_hex16(cpu_socketsB[i].up);
+ print_debug(" .down=");
+ print_debug_hex16(cpu_socketsB[i].down);
+ print_debug(" .across=");
+ print_debug_hex16(cpu_socketsB[i].across);
+ print_debug("\n");
+ }
+ _exit(0);
+}
diff --git a/util/romcc/tests/linux_test5.c b/util/romcc/tests/linux_test5.c
new file mode 100644
index 0000000000..55613c21b0
--- /dev/null
+++ b/util/romcc/tests/linux_test5.c
@@ -0,0 +1,359 @@
+#include "linux_syscall.h"
+#include "linux_console.h"
+
+int log2(int value)
+{
+ /* __builtin_bsr is a exactly equivalent to the x86 machine
+ * instruction with the exception that it returns -1
+ * when the value presented to it is zero.
+ * Otherwise __builtin_bsr returns the zero based index of
+ * the highest bit set.
+ */
+ return __builtin_bsr(value);
+}
+
+
+static int smbus_read_byte(unsigned device, unsigned address)
+{
+ static const unsigned char dimm[] = {
+0x80, 0x08, 0x07, 0x0d, 0x0a, 0x02, 0x48, 0x00, 0x04, 0x60, 0x70, 0x02, 0x82, 0x08, 0x08, 0x01,
+0x0e, 0x04, 0x0c, 0x01, 0x02, 0x20, 0x00, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48, 0x2a, 0x40,
+0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+
+0x80, 0x08, 0x07, 0x0d, 0x0a, 0x02, 0x48, 0x00, 0x04, 0x60, 0x70, 0x02, 0x82, 0x08, 0x08, 0x01,
+0x0e, 0x04, 0x0c, 0x01, 0x02, 0x20, 0x00, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48, 0x2a, 0x40,
+0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ };
+ return dimm[(device << 8) + address];
+}
+
+#define SMBUS_MEM_DEVICE_START 0x00
+#define SMBUS_MEM_DEVICE_END 0x01
+#define SMBUS_MEM_DEVICE_INC 1
+
+/* Function 2 */
+#define DRAM_CONFIG_HIGH 0x94
+#define DCH_MEMCLK_SHIFT 20
+#define DCH_MEMCLK_MASK 7
+#define DCH_MEMCLK_100MHZ 0
+#define DCH_MEMCLK_133MHZ 2
+#define DCH_MEMCLK_166MHZ 5
+#define DCH_MEMCLK_200MHZ 7
+
+/* Function 3 */
+#define NORTHBRIDGE_CAP 0xE8
+#define NBCAP_128Bit 0x0001
+#define NBCAP_MP 0x0002
+#define NBCAP_BIG_MP 0x0004
+#define NBCAP_ECC 0x0004
+#define NBCAP_CHIPKILL_ECC 0x0010
+#define NBCAP_MEMCLK_SHIFT 5
+#define NBCAP_MEMCLK_MASK 3
+#define NBCAP_MEMCLK_100MHZ 3
+#define NBCAP_MEMCLK_133MHZ 2
+#define NBCAP_MEMCLK_166MHZ 1
+#define NBCAP_MEMCLK_200MHZ 0
+#define NBCAP_MEMCTRL 0x0100
+
+typedef unsigned char uint8_t;
+typedef unsigned int uint32_t;
+
+static unsigned spd_to_dimm(unsigned device)
+{
+ return (device - SMBUS_MEM_DEVICE_START);
+}
+
+static void disable_dimm(unsigned index)
+{
+ print_debug("disabling dimm");
+ print_debug_hex8(index);
+ print_debug("\r\n");
+#if 0
+ pci_write_config32(PCI_DEV(0, 0x18, 2), DRAM_CSBASE + (((index << 1)+0)<<2), 0);
+ pci_write_config32(PCI_DEV(0, 0x18, 2), DRAM_CSBASE + (((index << 1)+1)<<2), 0);
+#endif
+}
+
+
+struct mem_param {
+ uint8_t cycle_time;
+ uint32_t dch_memclk;
+};
+
+static const struct mem_param *get_mem_param(unsigned min_cycle_time)
+{
+ static const struct mem_param speed[] = {
+ {
+ .cycle_time = 0xa0,
+ .dch_memclk = DCH_MEMCLK_100MHZ << DCH_MEMCLK_SHIFT,
+ },
+ {
+ .cycle_time = 0x75,
+ .dch_memclk = DCH_MEMCLK_133MHZ << DCH_MEMCLK_SHIFT,
+ },
+ {
+ .cycle_time = 0x60,
+ .dch_memclk = DCH_MEMCLK_166MHZ << DCH_MEMCLK_SHIFT,
+ },
+ {
+ .cycle_time = 0x50,
+ .dch_memclk = DCH_MEMCLK_200MHZ << DCH_MEMCLK_SHIFT,
+ },
+ {
+ .cycle_time = 0x00,
+ },
+ };
+ const struct mem_param *param;
+ for(param = &speed[0]; param->cycle_time ; param++) {
+ if (min_cycle_time > (param+1)->cycle_time) {
+ break;
+ }
+ }
+ if (!param->cycle_time) {
+ die("min_cycle_time to low");
+ }
+ return param;
+}
+
+#if 1
+static void debug(int c)
+{
+ print_debug_char(c);
+ print_debug_char('\r');
+ print_debug_char('\n');
+}
+#endif
+static const struct mem_param *spd_set_memclk(void)
+{
+ /* Compute the minimum cycle time for these dimms */
+ const struct mem_param *param;
+ unsigned min_cycle_time, min_latency;
+ unsigned device;
+ uint32_t value;
+
+ static const int latency_indicies[] = { 26, 23, 9 };
+ static const unsigned char min_cycle_times[] = {
+ [NBCAP_MEMCLK_200MHZ] = 0x50, /* 5ns */
+ [NBCAP_MEMCLK_166MHZ] = 0x60, /* 6ns */
+ [NBCAP_MEMCLK_133MHZ] = 0x75, /* 7.5ns */
+ [NBCAP_MEMCLK_100MHZ] = 0xa0, /* 10ns */
+ };
+
+
+#if 0
+ value = pci_read_config32(PCI_DEV(0, 0x18, 3), NORTHBRIDGE_CAP);
+#else
+ value = 0x50;
+#endif
+ min_cycle_time = min_cycle_times[(value >> NBCAP_MEMCLK_SHIFT) & NBCAP_MEMCLK_MASK];
+ min_latency = 2;
+
+#if 1
+ print_debug("min_cycle_time: ");
+ print_debug_hex8(min_cycle_time);
+ print_debug(" min_latency: ");
+ print_debug_hex8(min_latency);
+ print_debug("\r\n");
+#endif
+
+ /* Compute the least latency with the fastest clock supported
+ * by both the memory controller and the dimms.
+ */
+ for(device = SMBUS_MEM_DEVICE_START;
+ device <= SMBUS_MEM_DEVICE_END;
+ device += SMBUS_MEM_DEVICE_INC)
+ {
+ int new_cycle_time, new_latency;
+ int index;
+ int latencies;
+ int latency;
+
+ debug('A');
+ /* First find the supported CAS latencies
+ * Byte 18 for DDR SDRAM is interpreted:
+ * bit 0 == CAS Latency = 1.0
+ * bit 1 == CAS Latency = 1.5
+ * bit 2 == CAS Latency = 2.0
+ * bit 3 == CAS Latency = 2.5
+ * bit 4 == CAS Latency = 3.0
+ * bit 5 == CAS Latency = 3.5
+ * bit 6 == TBD
+ * bit 7 == TBD
+ */
+ new_cycle_time = 0xa0;
+ new_latency = 5;
+
+ latencies = smbus_read_byte(device, 18);
+ if (latencies <= 0) continue;
+
+ debug('B');
+ /* Compute the lowest cas latency supported */
+ latency = log2(latencies) -2;
+
+ /* Loop through and find a fast clock with a low latency */
+ for(index = 0; index < 3; index++, latency++) {
+ int value;
+ debug('C');
+ if ((latency < 2) || (latency > 4) ||
+ (!(latencies & (1 << latency)))) {
+ continue;
+ }
+ debug('D');
+ value = smbus_read_byte(device, latency_indicies[index]);
+ if (value < 0) continue;
+
+ debug('E');
+ /* Only increase the latency if we decreas the clock */
+ if ((value >= min_cycle_time) && (value < new_cycle_time)) {
+ new_cycle_time = value;
+ new_latency = latency;
+#if 1
+ print_debug("device: ");
+ print_debug_hex8(device);
+ print_debug(" new_cycle_time: ");
+ print_debug_hex8(new_cycle_time);
+ print_debug(" new_latency: ");
+ print_debug_hex8(new_latency);
+ print_debug("\r\n");
+#endif
+ }
+ debug('G');
+ }
+ debug('H');
+#if 1
+ print_debug("device: ");
+ print_debug_hex8(device);
+ print_debug(" new_cycle_time: ");
+ print_debug_hex8(new_cycle_time);
+ print_debug(" new_latency: ");
+ print_debug_hex8(new_latency);
+ print_debug("\r\n");
+#endif
+ if (new_latency > 4){
+ continue;
+ }
+ debug('I');
+ /* Does min_latency need to be increased? */
+ if (new_cycle_time > min_cycle_time) {
+ min_cycle_time = new_cycle_time;
+ }
+ /* Does min_cycle_time need to be increased? */
+ if (new_latency > min_latency) {
+ min_latency = new_latency;
+ }
+#if 1
+ print_debug("device: ");
+ print_debug_hex8(device);
+ print_debug(" min_cycle_time: ");
+ print_debug_hex8(min_cycle_time);
+ print_debug(" min_latency: ");
+ print_debug_hex8(min_latency);
+ print_debug("\r\n");
+#endif
+ }
+ /* Make a second pass through the dimms and disable
+ * any that cannot support the selected memclk and cas latency.
+ */
+ for(device = SMBUS_MEM_DEVICE_START;
+ device <= SMBUS_MEM_DEVICE_END;
+ device += SMBUS_MEM_DEVICE_INC)
+ {
+ int latencies;
+ int latency;
+ int index;
+ int value;
+ int dimm;
+ latencies = smbus_read_byte(device, 18);
+ if (latencies <= 0) {
+ goto dimm_err;
+ }
+
+ /* Compute the lowest cas latency supported */
+ latency = log2(latencies) -2;
+
+ /* Walk through searching for the selected latency */
+ for(index = 0; index < 3; index++, latency++) {
+ if (!(latencies & (1 << latency))) {
+ continue;
+ }
+ if (latency == min_latency)
+ break;
+ }
+ /* If I can't find the latency or my index is bad error */
+ if ((latency != min_latency) || (index >= 3)) {
+ goto dimm_err;
+ }
+
+ /* Read the min_cycle_time for this latency */
+ value = smbus_read_byte(device, latency_indicies[index]);
+
+ /* All is good if the selected clock speed
+ * is what I need or slower.
+ */
+ if (value <= min_cycle_time) {
+ continue;
+ }
+ /* Otherwise I have an error, disable the dimm */
+ dimm_err:
+ disable_dimm(spd_to_dimm(device));
+ }
+#if 1
+ print_debug("min_cycle_time: ");
+ print_debug_hex8(min_cycle_time);
+ print_debug(" min_latency: ");
+ print_debug_hex8(min_latency);
+ print_debug("\r\n");
+#endif
+ /* Now that I know the minimum cycle time lookup the memory parameters */
+ param = get_mem_param(min_cycle_time);
+
+#if 0
+ /* Update DRAM Config High with our selected memory speed */
+ value = pci_read_config32(PCI_DEV(0, 0x18, 2), DRAM_CONFIG_HIGH);
+ value &= ~(DCH_MEMCLK_MASK << DCH_MEMCLK_SHIFT);
+ value |= param->dch_memclk;
+ pci_write_config32(PCI_DEV(0, 0x18, 2), DRAM_CONFIG_HIGH, value);
+
+ static const unsigned latencies[] = { 1, 5, 2 };
+ /* Update DRAM Timing Low wiht our selected cas latency */
+ value = pci_read_config32(PCI_DEV(0, 0x18, 2), DRAM_CONFIG_LOW);
+ value &= ~7;
+ value |= latencies[min_latency - 2];
+ pci_write_config32(PCI_DEV(0, 0x18, 2), DRAM_CONFIG_LOW, value);
+#endif
+
+ return param;
+}
+
+static void main(void)
+{
+ const struct mem_param *param;
+ param = spd_set_memclk();
+ _exit(0);
+}
diff --git a/util/romcc/tests/linux_test6.c b/util/romcc/tests/linux_test6.c
new file mode 100644
index 0000000000..f93ab9273d
--- /dev/null
+++ b/util/romcc/tests/linux_test6.c
@@ -0,0 +1,17 @@
+#include "linux_syscall.h"
+#include "linux_console.h"
+
+static void main(void)
+{
+ static const int value[] = { 1, 0 };
+ const char *str;
+ if (value[1]) {
+ print_debug("A\r\n");
+ str = "Unbuffered\r\n";
+ } else {
+ print_debug("B\r\n");
+ str = "Registered\r\n";
+ }
+ print_debug(str);
+ _exit(0);
+}
diff --git a/util/romcc/tests/linux_test7.c b/util/romcc/tests/linux_test7.c
new file mode 100644
index 0000000000..409b6cbb44
--- /dev/null
+++ b/util/romcc/tests/linux_test7.c
@@ -0,0 +1,35 @@
+#include "linux_syscall.h"
+#include "linux_console.h"
+
+
+static void main(void)
+{
+ static const int cpu[] = { 0, 1, 2, 3 };
+ int i;
+ for(i = 0; i < sizeof(cpu)/sizeof(cpu[0]); i++) {
+ static const unsigned int register_values[] = {
+ 0x0000c144, 0x0000f8f8, 0x00000000,
+ 0x0000c14C, 0x0000f8f8, 0x00000001,
+ 0x0000c154, 0x0000f8f8, 0x00000002,
+ 0x0000c15C, 0x0000f8f8, 0x00000003,
+ 0x0000c164, 0x0000f8f8, 0x00000004,
+ 0x0000c16C, 0x0000f8f8, 0x00000005,
+ 0x0000c174, 0x0000f8f8, 0x00000006,
+ 0x0000c17C, 0x0000f8f8, 0x00000007,
+ };
+ int j;
+ int max = sizeof(register_values)/sizeof(register_values[0]);
+ for(j = 0; j < max; j += 3) {
+ print_debug("val[");
+ print_debug_hex8(j);
+ print_debug("]: ");
+ print_debug_hex32(register_values[j]);
+ print_debug_char(' ');
+ print_debug_hex32(register_values[j+1]);
+ print_debug_char(' ');
+ print_debug_hex32(register_values[j+2]);
+ print_debug_char('\n');
+ }
+ }
+ _exit(0);
+}
diff --git a/util/romcc/tests/linuxi386_syscall.h b/util/romcc/tests/linuxi386_syscall.h
new file mode 100644
index 0000000000..7eb513db36
--- /dev/null
+++ b/util/romcc/tests/linuxi386_syscall.h
@@ -0,0 +1,299 @@
+struct syscall_result {
+ long val;
+ int errno;
+};
+
+static struct syscall_result syscall_return(long result)
+{
+ struct syscall_result res;
+ if (((unsigned long)result) >= ((unsigned long)-125)) {
+ res.errno = - result;
+ res.val = -1;
+ } else {
+ res.errno = 0;
+ res.val = result;
+ }
+ return res;
+}
+
+static struct syscall_result syscall0(unsigned long nr)
+{
+ long res;
+ asm volatile(
+ "int $0x80"
+ : "=a" (res)
+ : "a" (nr));
+ return syscall_return(res);
+}
+
+static struct syscall_result syscall1(unsigned long nr, unsigned long arg1)
+{
+ long res;
+ asm volatile(
+ "int $0x80"
+ : "=a" (res)
+ : "a" (nr), "b" (arg1));
+ return syscall_return(res);
+
+}
+
+static struct syscall_result syscall2(unsigned long nr, unsigned long arg1, unsigned long arg2)
+{
+ long res;
+ asm volatile(
+ "int $0x80"
+ : "=a" (res)
+ : "a" (nr), "b" (arg1), "c" (arg2));
+ return syscall_return(res);
+
+}
+
+
+static struct syscall_result syscall3(unsigned long nr, unsigned long arg1, unsigned long arg2,
+ unsigned long arg3)
+{
+ long res;
+ asm volatile(
+ "int $0x80"
+ : "=a" (res)
+ : "a" (nr), "b" (arg1), "c" (arg2), "d" (arg3));
+ return syscall_return(res);
+
+}
+
+static struct syscall_result syscall4(unsigned long nr, unsigned long arg1, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4)
+{
+ long res;
+ asm volatile(
+ "int $0x80"
+ : "=a" (res)
+ : "a" (nr), "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4));
+ return syscall_return(res);
+
+}
+
+static struct syscall_result syscall5(unsigned long nr, unsigned long arg1, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4, unsigned long arg5)
+{
+ long res;
+ asm volatile(
+ "int $0x80"
+ : "=a" (res)
+ : "a" (nr), "b" (arg1), "c" (arg2), "d" (arg3),
+ "S" (arg4), "D" (arg5));
+ return syscall_return(res);
+
+}
+
+#define NR_exit 1
+#define NR_fork 2
+#define NR_read 3
+#define NR_write 4
+#define NR_open 5
+#define NR_close 6
+#define NR_waitpid 7
+#define NR_creat 8
+#define NR_link 9
+#define NR_unlink 10
+#define NR_execve 11
+#define NR_chdir 12
+#define NR_time 13
+#define NR_mknod 14
+#define NR_chmod 15
+#define NR_lchown 16
+#define NR_break 17
+#define NR_oldstat 18
+#define NR_lseek 19
+#define NR_getpid 20
+#define NR_mount 21
+#define NR_umount 22
+#define NR_setuid 23
+#define NR_getuid 24
+#define NR_stime 25
+#define NR_ptrace 26
+#define NR_alarm 27
+#define NR_oldfstat 28
+#define NR_pause 29
+#define NR_utime 30
+#define NR_stty 31
+#define NR_gtty 32
+#define NR_access 33
+#define NR_nice 34
+#define NR_ftime 35
+#define NR_sync 36
+#define NR_kill 37
+#define NR_rename 38
+#define NR_mkdir 39
+#define NR_rmdir 40
+#define NR_dup 41
+#define NR_pipe 42
+#define NR_times 43
+#define NR_prof 44
+#define NR_brk 45
+#define NR_setgid 46
+#define NR_getgid 47
+#define NR_signal 48
+#define NR_geteuid 49
+#define NR_getegid 50
+#define NR_acct 51
+#define NR_umount2 52
+#define NR_lock 53
+#define NR_ioctl 54
+#define NR_fcntl 55
+#define NR_mpx 56
+#define NR_setpgid 57
+#define NR_ulimit 58
+#define NR_oldolduname 59
+#define NR_umask 60
+#define NR_chroot 61
+#define NR_ustat 62
+#define NR_dup2 63
+#define NR_getppid 64
+#define NR_getpgrp 65
+#define NR_setsid 66
+#define NR_sigaction 67
+#define NR_sgetmask 68
+#define NR_ssetmask 69
+#define NR_setreuid 70
+#define NR_setregid 71
+#define NR_sigsuspend 72
+#define NR_sigpending 73
+#define NR_sethostname 74
+#define NR_setrlimit 75
+#define NR_getrlimit 76
+#define NR_getrusage 77
+#define NR_gettimeofday 78
+#define NR_settimeofday 79
+#define NR_getgroups 80
+#define NR_setgroups 81
+#define NR_select 82
+#define NR_symlink 83
+#define NR_oldlstat 84
+#define NR_readlink 85
+#define NR_uselib 86
+#define NR_swapon 87
+#define NR_reboot 88
+#define NR_readdir 89
+#define NR_mmap 90
+#define NR_munmap 91
+#define NR_truncate 92
+#define NR_ftruncate 93
+#define NR_fchmod 94
+#define NR_fchown 95
+#define NR_getpriority 96
+#define NR_setpriority 97
+#define NR_profil 98
+#define NR_statfs 99
+#define NR_fstatfs 100
+#define NR_ioperm 101
+#define NR_socketcall 102
+#define NR_syslog 103
+#define NR_setitimer 104
+#define NR_getitimer 105
+#define NR_stat 106
+#define NR_lstat 107
+#define NR_fstat 108
+#define NR_olduname 109
+#define NR_iopl 110
+#define NR_vhangup 111
+#define NR_idle 112
+#define NR_vm86old 113
+#define NR_wait4 114
+#define NR_swapoff 115
+#define NR_sysinfo 116
+#define NR_ipc 117
+#define NR_fsync 118
+#define NR_sigreturn 119
+#define NR_clone 120
+#define NR_setdomainname 121
+#define NR_uname 122
+#define NR_modify_ldt 123
+#define NR_adjtimex 124
+#define NR_mprotect 125
+#define NR_sigprocmask 126
+#define NR_create_module 127
+#define NR_init_module 128
+#define NR_delete_module 129
+#define NR_get_kernel_syms 130
+#define NR_quotactl 131
+#define NR_getpgid 132
+#define NR_fchdir 133
+#define NR_bdflush 134
+#define NR_sysfs 135
+#define NR_personality 136
+#define NR_afs_syscall 137 /* Syscall for Andrew File System */
+#define NR_setfsuid 138
+#define NR_setfsgid 139
+#define NR__llseek 140
+#define NR_getdents 141
+#define NR__newselect 142
+#define NR_flock 143
+#define NR_msync 144
+#define NR_readv 145
+#define NR_writev 146
+#define NR_getsid 147
+#define NR_fdatasync 148
+#define NR__sysctl 149
+#define NR_mlock 150
+#define NR_munlock 151
+#define NR_mlockall 152
+#define NR_munlockall 153
+#define NR_sched_setparam 154
+#define NR_sched_getparam 155
+#define NR_sched_setscheduler 156
+#define NR_sched_getscheduler 157
+#define NR_sched_yield 158
+#define NR_sched_get_priority_max 159
+#define NR_sched_get_priority_min 160
+#define NR_sched_rr_get_interval 161
+#define NR_nanosleep 162
+#define NR_mremap 163
+#define NR_setresuid 164
+#define NR_getresuid 165
+#define NR_vm86 166
+#define NR_query_module 167
+#define NR_poll 168
+#define NR_nfsservctl 169
+#define NR_setresgid 170
+#define NR_getresgid 171
+#define NR_prctl 172
+#define NR_rt_sigreturn 173
+#define NR_rt_sigaction 174
+#define NR_rt_sigprocmask 175
+#define NR_rt_sigpending 176
+#define NR_rt_sigtimedwait 177
+#define NR_rt_sigqueueinfo 178
+#define NR_rt_sigsuspend 179
+#define NR_pread 180
+#define NR_pwrite 181
+#define NR_chown 182
+#define NR_getcwd 183
+#define NR_capget 184
+#define NR_capset 185
+#define NR_sigaltstack 186
+#define NR_sendfile 187
+#define NR_getpmsg 188 /* some people actually want streams */
+#define NR_putpmsg 189 /* some people actually want streams */
+#define NR_vfork 190
+
+/* Standard file descriptors */
+#define STDIN_FILENO 0 /* Standard input */
+#define STDOUT_FILENO 1 /* Standard output */
+#define STDERR_FILENO 2 /* Standard error output */
+
+typedef long ssize_t;
+typedef unsigned long size_t;
+
+static ssize_t write(int fd, const void *buf, size_t count)
+{
+ struct syscall_result res;
+ res = syscall3(NR_write, fd, (unsigned long)buf, count);
+ return res.val;
+}
+
+static void _exit(int status)
+{
+ struct syscall_result res;
+ res = syscall1(NR_exit, status);
+}
diff --git a/util/romcc/tests/raminit_test6.c b/util/romcc/tests/raminit_test6.c
new file mode 100644
index 0000000000..a0c3f055be
--- /dev/null
+++ b/util/romcc/tests/raminit_test6.c
@@ -0,0 +1,2800 @@
+typedef unsigned char uint8_t;
+typedef signed char int8_t;
+typedef unsigned short uint16_t;
+typedef signed short int16_t;
+typedef unsigned int uint32_t;
+typedef signed int int32_t;
+
+typedef unsigned char uint_least8_t;
+typedef signed char int_least8_t;
+typedef unsigned short uint_least16_t;
+typedef signed short int_least16_t;
+typedef unsigned int uint_least32_t;
+typedef signed int int_least32_t;
+
+typedef unsigned char uint_fast8_t;
+typedef signed char int_fast8_t;
+typedef unsigned int uint_fast16_t;
+typedef signed int int_fast16_t;
+typedef unsigned int uint_fast32_t;
+typedef signed int int_fast32_t;
+
+typedef int intptr_t;
+typedef unsigned int uintptr_t;
+
+typedef long int intmax_t;
+typedef unsigned long int uintmax_t;
+
+static inline unsigned long apic_read(unsigned long reg)
+{
+ return *((volatile unsigned long *)(0xfee00000 +reg));
+}
+static inline void apic_write(unsigned long reg, unsigned long v)
+{
+ *((volatile unsigned long *)(0xfee00000 +reg)) = v;
+}
+static inline void apic_wait_icr_idle(void)
+{
+ do { } while ( apic_read( 0x300 ) & 0x01000 );
+}
+
+static void outb(unsigned char value, unsigned short port)
+{
+ __builtin_outb(value, port);
+}
+static void outw(unsigned short value, unsigned short port)
+{
+ __builtin_outw(value, port);
+}
+static void outl(unsigned int value, unsigned short port)
+{
+ __builtin_outl(value, port);
+}
+static unsigned char inb(unsigned short port)
+{
+ return __builtin_inb(port);
+}
+static unsigned char inw(unsigned short port)
+{
+ return __builtin_inw(port);
+}
+static unsigned char inl(unsigned short port)
+{
+ return __builtin_inl(port);
+}
+static inline void outsb(uint16_t port, const void *addr, unsigned long count)
+{
+ __asm__ __volatile__ (
+ "cld ; rep ; outsb "
+ : "=S" (addr), "=c" (count)
+ : "d"(port), "0"(addr), "1" (count)
+ );
+}
+static inline void outsw(uint16_t port, const void *addr, unsigned long count)
+{
+ __asm__ __volatile__ (
+ "cld ; rep ; outsw "
+ : "=S" (addr), "=c" (count)
+ : "d"(port), "0"(addr), "1" (count)
+ );
+}
+static inline void outsl(uint16_t port, const void *addr, unsigned long count)
+{
+ __asm__ __volatile__ (
+ "cld ; rep ; outsl "
+ : "=S" (addr), "=c" (count)
+ : "d"(port), "0"(addr), "1" (count)
+ );
+}
+static inline void insb(uint16_t port, void *addr, unsigned long count)
+{
+ __asm__ __volatile__ (
+ "cld ; rep ; insb "
+ : "=D" (addr), "=c" (count)
+ : "d"(port), "0"(addr), "1" (count)
+ );
+}
+static inline void insw(uint16_t port, void *addr, unsigned long count)
+{
+ __asm__ __volatile__ (
+ "cld ; rep ; insw "
+ : "=D" (addr), "=c" (count)
+ : "d"(port), "0"(addr), "1" (count)
+ );
+}
+static inline void insl(uint16_t port, void *addr, unsigned long count)
+{
+ __asm__ __volatile__ (
+ "cld ; rep ; insl "
+ : "=D" (addr), "=c" (count)
+ : "d"(port), "0"(addr), "1" (count)
+ );
+}
+static inline void pnp_write_config(unsigned char port, unsigned char value, unsigned char reg)
+{
+ outb(reg, port);
+ outb(value, port +1);
+}
+static inline unsigned char pnp_read_config(unsigned char port, unsigned char reg)
+{
+ outb(reg, port);
+ return inb(port +1);
+}
+static inline void pnp_set_logical_device(unsigned char port, int device)
+{
+ pnp_write_config(port, device, 0x07);
+}
+static inline void pnp_set_enable(unsigned char port, int enable)
+{
+ pnp_write_config(port, enable?0x1:0x0, 0x30);
+}
+static inline int pnp_read_enable(unsigned char port)
+{
+ return !!pnp_read_config(port, 0x30);
+}
+static inline void pnp_set_iobase0(unsigned char port, unsigned iobase)
+{
+ pnp_write_config(port, (iobase >> 8) & 0xff, 0x60);
+ pnp_write_config(port, iobase & 0xff, 0x61);
+}
+static inline void pnp_set_iobase1(unsigned char port, unsigned iobase)
+{
+ pnp_write_config(port, (iobase >> 8) & 0xff, 0x62);
+ pnp_write_config(port, iobase & 0xff, 0x63);
+}
+static inline void pnp_set_irq0(unsigned char port, unsigned irq)
+{
+ pnp_write_config(port, irq, 0x70);
+}
+static inline void pnp_set_irq1(unsigned char port, unsigned irq)
+{
+ pnp_write_config(port, irq, 0x72);
+}
+static inline void pnp_set_drq(unsigned char port, unsigned drq)
+{
+ pnp_write_config(port, drq & 0xff, 0x74);
+}
+static void hlt(void)
+{
+ __builtin_hlt();
+}
+typedef __builtin_div_t div_t;
+typedef __builtin_ldiv_t ldiv_t;
+typedef __builtin_udiv_t udiv_t;
+typedef __builtin_uldiv_t uldiv_t;
+static div_t div(int numer, int denom)
+{
+ return __builtin_div(numer, denom);
+}
+static ldiv_t ldiv(long numer, long denom)
+{
+ return __builtin_ldiv(numer, denom);
+}
+static udiv_t udiv(unsigned numer, unsigned denom)
+{
+ return __builtin_udiv(numer, denom);
+}
+static uldiv_t uldiv(unsigned long numer, unsigned long denom)
+{
+ return __builtin_uldiv(numer, denom);
+}
+int log2(int value)
+{
+
+ return __builtin_bsr(value);
+}
+typedef unsigned device_t;
+static unsigned char pci_read_config8(device_t dev, unsigned where)
+{
+ unsigned addr;
+ addr = dev | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ return inb(0xCFC + (addr & 3));
+}
+static unsigned short pci_read_config16(device_t dev, unsigned where)
+{
+ unsigned addr;
+ addr = dev | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ return inw(0xCFC + (addr & 2));
+}
+static unsigned int pci_read_config32(device_t dev, unsigned where)
+{
+ unsigned addr;
+ addr = dev | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ return inl(0xCFC);
+}
+static void pci_write_config8(device_t dev, unsigned where, unsigned char value)
+{
+ unsigned addr;
+ addr = dev | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ outb(value, 0xCFC + (addr & 3));
+}
+static void pci_write_config16(device_t dev, unsigned where, unsigned short value)
+{
+ unsigned addr;
+ addr = dev | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ outw(value, 0xCFC + (addr & 2));
+}
+static void pci_write_config32(device_t dev, unsigned where, unsigned int value)
+{
+ unsigned addr;
+ addr = dev | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ outl(value, 0xCFC);
+}
+static device_t pci_locate_device(unsigned pci_id, device_t dev)
+{
+ for(; dev <= ( ((( 255 ) & 0xFF) << 16) | ((( 31 ) & 0x1f) << 11) | ((( 7 ) & 0x7) << 8)) ; dev += ( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 1 ) & 0x7) << 8)) ) {
+ unsigned int id;
+ id = pci_read_config32(dev, 0);
+ if (id == pci_id) {
+ return dev;
+ }
+ }
+ return (0xffffffffU) ;
+}
+
+
+
+
+
+static int uart_can_tx_byte(void)
+{
+ return inb(1016 + 0x05 ) & 0x20;
+}
+static void uart_wait_to_tx_byte(void)
+{
+ while(!uart_can_tx_byte())
+ ;
+}
+static void uart_wait_until_sent(void)
+{
+ while(!(inb(1016 + 0x05 ) & 0x40))
+ ;
+}
+static void uart_tx_byte(unsigned char data)
+{
+ uart_wait_to_tx_byte();
+ outb(data, 1016 + 0x00 );
+
+ uart_wait_until_sent();
+}
+static void uart_init(void)
+{
+
+ outb(0x0, 1016 + 0x01 );
+
+ outb(0x01, 1016 + 0x02 );
+
+ outb(0x80 | 3 , 1016 + 0x03 );
+ outb((115200/ 115200 ) & 0xFF, 1016 + 0x00 );
+ outb(((115200/ 115200 ) >> 8) & 0xFF, 1016 + 0x01 );
+ outb(3 , 1016 + 0x03 );
+}
+
+static void __console_tx_byte(unsigned char byte)
+{
+ uart_tx_byte(byte);
+}
+static void __console_tx_nibble(unsigned nibble)
+{
+ unsigned char digit;
+ digit = nibble + '0';
+ if (digit > '9') {
+ digit += 39;
+ }
+ __console_tx_byte(digit);
+}
+static void __console_tx_char(int loglevel, unsigned char byte)
+{
+ if (8 > loglevel) {
+ uart_tx_byte(byte);
+ }
+}
+static void __console_tx_hex8(int loglevel, unsigned char value)
+{
+ if (8 > loglevel) {
+ __console_tx_nibble((value >> 4U) & 0x0fU);
+ __console_tx_nibble(value & 0x0fU);
+ }
+}
+static void __console_tx_hex16(int loglevel, unsigned short value)
+{
+ if (8 > loglevel) {
+ __console_tx_nibble((value >> 12U) & 0x0fU);
+ __console_tx_nibble((value >> 8U) & 0x0fU);
+ __console_tx_nibble((value >> 4U) & 0x0fU);
+ __console_tx_nibble(value & 0x0fU);
+ }
+}
+static void __console_tx_hex32(int loglevel, unsigned int value)
+{
+ if (8 > loglevel) {
+ __console_tx_nibble((value >> 28U) & 0x0fU);
+ __console_tx_nibble((value >> 24U) & 0x0fU);
+ __console_tx_nibble((value >> 20U) & 0x0fU);
+ __console_tx_nibble((value >> 16U) & 0x0fU);
+ __console_tx_nibble((value >> 12U) & 0x0fU);
+ __console_tx_nibble((value >> 8U) & 0x0fU);
+ __console_tx_nibble((value >> 4U) & 0x0fU);
+ __console_tx_nibble(value & 0x0fU);
+ }
+}
+static void __console_tx_string(int loglevel, const char *str)
+{
+ if (8 > loglevel) {
+ unsigned char ch;
+ while((ch = *str++) != '\0') {
+ __console_tx_byte(ch);
+ }
+ }
+}
+static void print_emerg_char(unsigned char byte) { __console_tx_char(0 , byte); }
+static void print_emerg_hex8(unsigned char value){ __console_tx_hex8(0 , value); }
+static void print_emerg_hex16(unsigned short value){ __console_tx_hex16(0 , value); }
+static void print_emerg_hex32(unsigned int value) { __console_tx_hex32(0 , value); }
+static void print_emerg(const char *str) { __console_tx_string(0 , str); }
+static void print_alert_char(unsigned char byte) { __console_tx_char(1 , byte); }
+static void print_alert_hex8(unsigned char value) { __console_tx_hex8(1 , value); }
+static void print_alert_hex16(unsigned short value){ __console_tx_hex16(1 , value); }
+static void print_alert_hex32(unsigned int value) { __console_tx_hex32(1 , value); }
+static void print_alert(const char *str) { __console_tx_string(1 , str); }
+static void print_crit_char(unsigned char byte) { __console_tx_char(2 , byte); }
+static void print_crit_hex8(unsigned char value) { __console_tx_hex8(2 , value); }
+static void print_crit_hex16(unsigned short value){ __console_tx_hex16(2 , value); }
+static void print_crit_hex32(unsigned int value) { __console_tx_hex32(2 , value); }
+static void print_crit(const char *str) { __console_tx_string(2 , str); }
+static void print_err_char(unsigned char byte) { __console_tx_char(3 , byte); }
+static void print_err_hex8(unsigned char value) { __console_tx_hex8(3 , value); }
+static void print_err_hex16(unsigned short value){ __console_tx_hex16(3 , value); }
+static void print_err_hex32(unsigned int value) { __console_tx_hex32(3 , value); }
+static void print_err(const char *str) { __console_tx_string(3 , str); }
+static void print_warning_char(unsigned char byte) { __console_tx_char(4 , byte); }
+static void print_warning_hex8(unsigned char value) { __console_tx_hex8(4 , value); }
+static void print_warning_hex16(unsigned short value){ __console_tx_hex16(4 , value); }
+static void print_warning_hex32(unsigned int value) { __console_tx_hex32(4 , value); }
+static void print_warning(const char *str) { __console_tx_string(4 , str); }
+static void print_notice_char(unsigned char byte) { __console_tx_char(5 , byte); }
+static void print_notice_hex8(unsigned char value) { __console_tx_hex8(5 , value); }
+static void print_notice_hex16(unsigned short value){ __console_tx_hex16(5 , value); }
+static void print_notice_hex32(unsigned int value) { __console_tx_hex32(5 , value); }
+static void print_notice(const char *str) { __console_tx_string(5 , str); }
+static void print_info_char(unsigned char byte) { __console_tx_char(6 , byte); }
+static void print_info_hex8(unsigned char value) { __console_tx_hex8(6 , value); }
+static void print_info_hex16(unsigned short value){ __console_tx_hex16(6 , value); }
+static void print_info_hex32(unsigned int value) { __console_tx_hex32(6 , value); }
+static void print_info(const char *str) { __console_tx_string(6 , str); }
+static void print_debug_char(unsigned char byte) { __console_tx_char(7 , byte); }
+static void print_debug_hex8(unsigned char value) { __console_tx_hex8(7 , value); }
+static void print_debug_hex16(unsigned short value){ __console_tx_hex16(7 , value); }
+static void print_debug_hex32(unsigned int value) { __console_tx_hex32(7 , value); }
+static void print_debug(const char *str) { __console_tx_string(7 , str); }
+static void print_spew_char(unsigned char byte) { __console_tx_char(8 , byte); }
+static void print_spew_hex8(unsigned char value) { __console_tx_hex8(8 , value); }
+static void print_spew_hex16(unsigned short value){ __console_tx_hex16(8 , value); }
+static void print_spew_hex32(unsigned int value) { __console_tx_hex32(8 , value); }
+static void print_spew(const char *str) { __console_tx_string(8 , str); }
+static void console_init(void)
+{
+ static const char console_test[] =
+ "\r\n\r\nLinuxBIOS-"
+ "1.1.4"
+ ".0Fallback"
+ " "
+ "Thu Oct 9 20:29:48 MDT 2003"
+ " starting...\r\n";
+ print_info(console_test);
+}
+static void die(const char *str)
+{
+ print_emerg(str);
+ do {
+ hlt();
+ } while(1);
+}
+static void write_phys(unsigned long addr, unsigned long value)
+{
+ asm volatile(
+ "movnti %1, (%0)"
+ :
+ : "r" (addr), "r" (value)
+ :
+ );
+}
+static unsigned long read_phys(unsigned long addr)
+{
+ volatile unsigned long *ptr;
+ ptr = (void *)addr;
+ return *ptr;
+}
+static void ram_fill(unsigned long start, unsigned long stop)
+{
+ unsigned long addr;
+
+ print_debug("DRAM fill: ");
+ print_debug_hex32(start);
+ print_debug("-");
+ print_debug_hex32(stop);
+ print_debug("\r\n");
+ for(addr = start; addr < stop ; addr += 4) {
+
+ if (!(addr & 0xffff)) {
+ print_debug_hex32(addr);
+ print_debug("\r");
+ }
+ write_phys(addr, addr);
+ };
+
+ print_debug_hex32(addr);
+ print_debug("\r\nDRAM filled\r\n");
+}
+static void ram_verify(unsigned long start, unsigned long stop)
+{
+ unsigned long addr;
+
+ print_debug("DRAM verify: ");
+ print_debug_hex32(start);
+ print_debug_char('-');
+ print_debug_hex32(stop);
+ print_debug("\r\n");
+ for(addr = start; addr < stop ; addr += 4) {
+ unsigned long value;
+
+ if (!(addr & 0xffff)) {
+ print_debug_hex32(addr);
+ print_debug("\r");
+ }
+ value = read_phys(addr);
+ if (value != addr) {
+
+ print_err_hex32(addr);
+ print_err_char(':');
+ print_err_hex32(value);
+ print_err("\r\n");
+ }
+ }
+
+ print_debug_hex32(addr);
+ print_debug("\r\nDRAM verified\r\n");
+}
+void ram_check(unsigned long start, unsigned long stop)
+{
+ int result;
+
+ print_debug("Testing DRAM : ");
+ print_debug_hex32(start);
+ print_debug("-");
+ print_debug_hex32(stop);
+ print_debug("\r\n");
+ ram_fill(start, stop);
+ ram_verify(start, stop);
+ print_debug("Done.\r\n");
+}
+static int enumerate_ht_chain(unsigned link)
+{
+
+ unsigned next_unitid, last_unitid;
+ int reset_needed = 0;
+ next_unitid = 1;
+ do {
+ uint32_t id;
+ uint8_t hdr_type, pos;
+ last_unitid = next_unitid;
+ id = pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x00 );
+
+ if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+ (((id >> 16) & 0xffff) == 0xffff) ||
+ (((id >> 16) & 0xffff) == 0x0000)) {
+ break;
+ }
+ hdr_type = pci_read_config8(( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x0e );
+ pos = 0;
+ hdr_type &= 0x7f;
+ if ((hdr_type == 0 ) ||
+ (hdr_type == 1 )) {
+ pos = pci_read_config8(( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x34 );
+ }
+ while(pos != 0) {
+ uint8_t cap;
+ cap = pci_read_config8(( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , pos + 0 );
+ if (cap == 0x08 ) {
+ uint16_t flags;
+ flags = pci_read_config16(( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , pos + 2 );
+ if ((flags >> 13) == 0) {
+ unsigned count;
+ flags &= ~0x1f;
+ flags |= next_unitid & 0x1f;
+ count = (flags >> 5) & 0x1f;
+ pci_write_config16(( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , pos + 2 , flags);
+ next_unitid += count;
+ break;
+ }
+ }
+ pos = pci_read_config8(( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , pos + 1 );
+ }
+ } while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
+ return reset_needed;
+}
+static void enable_smbus(void)
+{
+ device_t dev;
+ dev = pci_locate_device((((( 0x746b ) & 0xFFFF) << 16) | (( 0x1022 ) & 0xFFFF)) , 0);
+ if (dev == (0xffffffffU) ) {
+ die("SMBUS controller not found\r\n");
+ }
+ uint8_t enable;
+ print_debug("SMBus controller enabled\r\n");
+ pci_write_config32(dev, 0x58, 0x0f00 | 1);
+ enable = pci_read_config8(dev, 0x41);
+ pci_write_config8(dev, 0x41, enable | (1 << 7));
+
+ outw(inw(0x0f00 + 0xe0 ), 0x0f00 + 0xe0 );
+}
+static inline void smbus_delay(void)
+{
+ outb(0x80, 0x80);
+}
+static int smbus_wait_until_ready(void)
+{
+ unsigned long loops;
+ loops = (100*1000*10) ;
+ do {
+ unsigned short val;
+ smbus_delay();
+ val = inw(0x0f00 + 0xe0 );
+ if ((val & 0x800) == 0) {
+ break;
+ }
+ if(loops == ((100*1000*10) / 2)) {
+ outw(inw(0x0f00 + 0xe0 ),
+ 0x0f00 + 0xe0 );
+ }
+ } while(--loops);
+ return loops?0:-2;
+}
+static int smbus_wait_until_done(void)
+{
+ unsigned long loops;
+ loops = (100*1000*10) ;
+ do {
+ unsigned short val;
+ smbus_delay();
+
+ val = inw(0x0f00 + 0xe0 );
+ if (((val & 0x8) == 0) | ((val & 0x437) != 0)) {
+ break;
+ }
+ } while(--loops);
+ return loops?0:-3;
+}
+static int smbus_read_byte(unsigned device, unsigned address)
+{
+ unsigned char global_control_register;
+ unsigned char global_status_register;
+ unsigned char byte;
+ if (smbus_wait_until_ready() < 0) {
+ return -2;
+ }
+
+
+
+ outw(inw(0x0f00 + 0xe2 ) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), 0x0f00 + 0xe2 );
+
+ outw(((device & 0x7f) << 1) | 1, 0x0f00 + 0xe4 );
+
+ outb(address & 0xFF, 0x0f00 + 0xe8 );
+
+ outw((inw(0x0f00 + 0xe2 ) & ~7) | (0x2), 0x0f00 + 0xe2 );
+
+
+ outw(inw(0x0f00 + 0xe0 ), 0x0f00 + 0xe0 );
+
+ outw(0, 0x0f00 + 0xe6 );
+
+ outw((inw(0x0f00 + 0xe2 ) | (1 << 3)), 0x0f00 + 0xe2 );
+
+ if (smbus_wait_until_done() < 0) {
+ return -3;
+ }
+ global_status_register = inw(0x0f00 + 0xe0 );
+
+ byte = inw(0x0f00 + 0xe6 ) & 0xff;
+ if (global_status_register != (1 << 4)) {
+ return -1;
+ }
+ return byte;
+}
+static void smbus_write_byte(unsigned device, unsigned address, unsigned char val)
+{
+ return;
+}
+struct mem_controller {
+ unsigned node_id;
+ device_t f0, f1, f2, f3;
+ uint8_t channel0[4];
+ uint8_t channel1[4];
+};
+typedef __builtin_msr_t msr_t;
+static msr_t rdmsr(unsigned long index)
+{
+ return __builtin_rdmsr(index);
+}
+static void wrmsr(unsigned long index, msr_t msr)
+{
+ __builtin_wrmsr(index, msr.lo, msr.hi);
+}
+struct tsc_struct {
+ unsigned lo;
+ unsigned hi;
+};
+typedef struct tsc_struct tsc_t;
+static tsc_t rdtsc(void)
+{
+ tsc_t res;
+ asm ("rdtsc"
+ : "=a" (res.lo), "=d"(res.hi)
+ :
+ :
+ );
+ return res;
+}
+void init_timer(void)
+{
+
+ apic_write(0x320 , (1 << 17)|(1<< 16)|(0 << 12)|(0 << 0));
+
+ apic_write(0x3E0 , 0xB );
+
+ apic_write(0x380 , 0xffffffff);
+}
+void udelay(unsigned usecs)
+{
+ uint32_t start, value, ticks;
+
+ ticks = usecs * 200;
+ start = apic_read(0x390 );
+ do {
+ value = apic_read(0x390 );
+ } while((start - value) < ticks);
+
+}
+void mdelay(unsigned msecs)
+{
+ unsigned i;
+ for(i = 0; i < msecs; i++) {
+ udelay(1000);
+ }
+}
+void delay(unsigned secs)
+{
+ unsigned i;
+ for(i = 0; i < secs; i++) {
+ mdelay(1000);
+ }
+}
+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));
+ return bsp;
+}
+static int cpu_init_detected(void)
+{
+ unsigned long htic;
+ htic = pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x6c );
+ return !!(htic & (1<<6) );
+}
+static int bios_reset_detected(void)
+{
+ unsigned long htic;
+ htic = pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x6c );
+ return (htic & (1<<4) ) && !(htic & (1<<5) );
+}
+static int cold_reset_detected(void)
+{
+ unsigned long htic;
+ htic = pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x6c );
+ return !(htic & (1<<4) );
+}
+static void distinguish_cpu_resets(unsigned node_id)
+{
+ uint32_t htic;
+ device_t device;
+ device = ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 + node_id ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ;
+ htic = pci_read_config32(device, 0x6c );
+ htic |= (1<<4) | (1<<5) | (1<<6) ;
+ pci_write_config32(device, 0x6c , htic);
+}
+static void set_bios_reset(void)
+{
+ unsigned long htic;
+ htic = pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x6c );
+ htic &= ~(1<<5) ;
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x6c , htic);
+}
+static void print_debug_pci_dev(unsigned dev)
+{
+ print_debug("PCI: ");
+ print_debug_hex8((dev >> 16) & 0xff);
+ print_debug_char(':');
+ print_debug_hex8((dev >> 11) & 0x1f);
+ print_debug_char('.');
+ print_debug_hex8((dev >> 8) & 7);
+}
+static void print_pci_devices(void)
+{
+ device_t dev;
+ for(dev = ( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ;
+ dev <= ( ((( 0 ) & 0xFF) << 16) | ((( 0x1f ) & 0x1f) << 11) | ((( 0x7 ) & 0x7) << 8)) ;
+ dev += ( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 1 ) & 0x7) << 8)) ) {
+ uint32_t id;
+ id = pci_read_config32(dev, 0x00 );
+ if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+ (((id >> 16) & 0xffff) == 0xffff) ||
+ (((id >> 16) & 0xffff) == 0x0000)) {
+ continue;
+ }
+ print_debug_pci_dev(dev);
+ print_debug("\r\n");
+ }
+}
+static void dump_pci_device(unsigned dev)
+{
+ int i;
+ print_debug_pci_dev(dev);
+ print_debug("\r\n");
+
+ for(i = 0; i <= 255; i++) {
+ unsigned char val;
+ if ((i & 0x0f) == 0) {
+ print_debug_hex8(i);
+ print_debug_char(':');
+ }
+ val = pci_read_config8(dev, i);
+ print_debug_char(' ');
+ print_debug_hex8(val);
+ if ((i & 0x0f) == 0x0f) {
+ print_debug("\r\n");
+ }
+ }
+}
+static void dump_pci_devices(void)
+{
+ device_t dev;
+ for(dev = ( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ;
+ dev <= ( ((( 0 ) & 0xFF) << 16) | ((( 0x1f ) & 0x1f) << 11) | ((( 0x7 ) & 0x7) << 8)) ;
+ dev += ( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 1 ) & 0x7) << 8)) ) {
+ uint32_t id;
+ id = pci_read_config32(dev, 0x00 );
+ if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+ (((id >> 16) & 0xffff) == 0xffff) ||
+ (((id >> 16) & 0xffff) == 0x0000)) {
+ continue;
+ }
+ dump_pci_device(dev);
+ }
+}
+static void dump_spd_registers(const struct mem_controller *ctrl)
+{
+ int i;
+ print_debug("\r\n");
+ for(i = 0; i < 4; i++) {
+ unsigned device;
+ device = ctrl->channel0[i];
+ if (device) {
+ int j;
+ print_debug("dimm: ");
+ print_debug_hex8(i);
+ print_debug(".0: ");
+ print_debug_hex8(device);
+ for(j = 0; j < 256; j++) {
+ int status;
+ unsigned char byte;
+ if ((j & 0xf) == 0) {
+ print_debug("\r\n");
+ print_debug_hex8(j);
+ print_debug(": ");
+ }
+ status = smbus_read_byte(device, j);
+ if (status < 0) {
+ print_debug("bad device\r\n");
+ break;
+ }
+ byte = status & 0xff;
+ print_debug_hex8(byte);
+ print_debug_char(' ');
+ }
+ print_debug("\r\n");
+ }
+ device = ctrl->channel1[i];
+ if (device) {
+ int j;
+ print_debug("dimm: ");
+ print_debug_hex8(i);
+ print_debug(".1: ");
+ print_debug_hex8(device);
+ for(j = 0; j < 256; j++) {
+ int status;
+ unsigned char byte;
+ if ((j & 0xf) == 0) {
+ print_debug("\r\n");
+ print_debug_hex8(j);
+ print_debug(": ");
+ }
+ status = smbus_read_byte(device, j);
+ if (status < 0) {
+ print_debug("bad device\r\n");
+ break;
+ }
+ byte = status & 0xff;
+ print_debug_hex8(byte);
+ print_debug_char(' ');
+ }
+ print_debug("\r\n");
+ }
+ }
+}
+
+static unsigned int cpuid(unsigned int op)
+{
+ unsigned int ret;
+ unsigned dummy2,dummy3,dummy4;
+ asm volatile (
+ "cpuid"
+ : "=a" (ret), "=b" (dummy2), "=c" (dummy3), "=d" (dummy4)
+ : "a" (op)
+ );
+ return ret;
+}
+static int is_cpu_rev_a0(void)
+{
+ return (cpuid(1) & 0xffff) == 0x0f10;
+}
+static int is_cpu_pre_c0(void)
+{
+ return (cpuid(1) & 0xffef) < 0x0f48;
+}
+static void memreset_setup(void)
+{
+ if (is_cpu_pre_c0()) {
+
+ outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), 0x0f00 + 0xc0 + 28);
+
+ outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), 0x0f00 + 0xc0 + 29);
+ }
+ else {
+
+ outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), 0x0f00 + 0xc0 + 29);
+ }
+}
+static void memreset(int controllers, const struct mem_controller *ctrl)
+{
+ if (is_cpu_pre_c0()) {
+ udelay(800);
+
+ outb((0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), 0x0f00 + 0xc0 + 28);
+ udelay(90);
+ }
+}
+static unsigned int generate_row(uint8_t node, uint8_t row, uint8_t maxnodes)
+{
+
+ uint32_t ret=0x00010101;
+ static const unsigned int rows_2p[2][2] = {
+ { 0x00050101, 0x00010404 },
+ { 0x00010404, 0x00050101 }
+ };
+ if(maxnodes>2) {
+ print_debug("this mainboard is only designed for 2 cpus\r\n");
+ maxnodes=2;
+ }
+ if (!(node>=maxnodes || row>=maxnodes)) {
+ ret=rows_2p[node][row];
+ }
+ return ret;
+}
+static inline int spd_read_byte(unsigned device, unsigned address)
+{
+ return smbus_read_byte(device, address);
+}
+
+static void coherent_ht_mainboard(unsigned cpus)
+{
+}
+
+void cpu_ldtstop(unsigned cpus)
+{
+ uint32_t tmp;
+ device_t dev;
+ unsigned cnt;
+ for(cnt=0; cnt<cpus; cnt++) {
+
+ pci_write_config8(( ((( 0 ) & 0xFF) << 16) | ((( 24 ) & 0x1f) << 11) | ((( 3 ) & 0x7) << 8)) ,0x81,0x23);
+
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24 ) & 0x1f) << 11) | ((( 3 ) & 0x7) << 8)) ,0xd4,0x00000701);
+
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24 ) & 0x1f) << 11) | ((( 3 ) & 0x7) << 8)) ,0xd8,0x00000000);
+
+ tmp=pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24 ) & 0x1f) << 11) | ((( 2 ) & 0x7) << 8)) ,0x90);
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24 ) & 0x1f) << 11) | ((( 2 ) & 0x7) << 8)) ,0x90, tmp | (1<<24) );
+ }
+}
+
+
+
+
+
+static void setup_resource_map(const unsigned int *register_values, int max)
+{
+ int i;
+ print_debug("setting up resource map....\r\n");
+ for(i = 0; i < max; i += 3) {
+ device_t dev;
+ unsigned where;
+ unsigned long reg;
+ dev = register_values[i] & ~0xff;
+ where = register_values[i] & 0xff;
+ reg = pci_read_config32(dev, where);
+ reg &= register_values[i+1];
+ reg |= register_values[i+2];
+ pci_write_config32(dev, where, reg);
+ }
+ print_debug("done.\r\n");
+}
+static void setup_default_resource_map(void)
+{
+ static const unsigned int register_values[] = {
+
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x44 ) & 0xFF)) , 0x0000f8f8, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x4C ) & 0xFF)) , 0x0000f8f8, 0x00000001,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x54 ) & 0xFF)) , 0x0000f8f8, 0x00000002,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x5C ) & 0xFF)) , 0x0000f8f8, 0x00000003,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x64 ) & 0xFF)) , 0x0000f8f8, 0x00000004,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x6C ) & 0xFF)) , 0x0000f8f8, 0x00000005,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x74 ) & 0xFF)) , 0x0000f8f8, 0x00000006,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x7C ) & 0xFF)) , 0x0000f8f8, 0x00000007,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x40 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x48 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x50 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x58 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x60 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x68 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x70 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x78 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x84 ) & 0xFF)) , 0x00000048, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x8C ) & 0xFF)) , 0x00000048, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x94 ) & 0xFF)) , 0x00000048, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x9C ) & 0xFF)) , 0x00000048, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xA4 ) & 0xFF)) , 0x00000048, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xAC ) & 0xFF)) , 0x00000048, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xB4 ) & 0xFF)) , 0x00000048, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xBC ) & 0xFF)) , 0x00000048, 0x00ffff00,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x80 ) & 0xFF)) , 0x000000f0, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x88 ) & 0xFF)) , 0x000000f0, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x90 ) & 0xFF)) , 0x000000f0, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x98 ) & 0xFF)) , 0x000000f0, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xA0 ) & 0xFF)) , 0x000000f0, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xA8 ) & 0xFF)) , 0x000000f0, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xB0 ) & 0xFF)) , 0x000000f0, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xB8 ) & 0xFF)) , 0x000000f0, 0x00fc0003,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xC4 ) & 0xFF)) , 0xFE000FC8, 0x01fff000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xCC ) & 0xFF)) , 0xFE000FC8, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xD4 ) & 0xFF)) , 0xFE000FC8, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xDC ) & 0xFF)) , 0xFE000FC8, 0x00000000,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xC0 ) & 0xFF)) , 0xFE000FCC, 0x00000003,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xC8 ) & 0xFF)) , 0xFE000FCC, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xD0 ) & 0xFF)) , 0xFE000FCC, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xD8 ) & 0xFF)) , 0xFE000FCC, 0x00000000,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xE0 ) & 0xFF)) , 0x0000FC88, 0xff000003,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xE4 ) & 0xFF)) , 0x0000FC88, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xE8 ) & 0xFF)) , 0x0000FC88, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xEC ) & 0xFF)) , 0x0000FC88, 0x00000000,
+ };
+ int max;
+ max = sizeof(register_values)/sizeof(register_values[0]);
+ setup_resource_map(register_values, max);
+}
+static void sdram_set_registers(const struct mem_controller *ctrl)
+{
+ static const unsigned int register_values[] = {
+
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x44 ) & 0xFF)) , 0x0000f8f8, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x4C ) & 0xFF)) , 0x0000f8f8, 0x00000001,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x54 ) & 0xFF)) , 0x0000f8f8, 0x00000002,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x5C ) & 0xFF)) , 0x0000f8f8, 0x00000003,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x64 ) & 0xFF)) , 0x0000f8f8, 0x00000004,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x6C ) & 0xFF)) , 0x0000f8f8, 0x00000005,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x74 ) & 0xFF)) , 0x0000f8f8, 0x00000006,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x7C ) & 0xFF)) , 0x0000f8f8, 0x00000007,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x40 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x48 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x50 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x58 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x60 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x68 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x70 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x78 ) & 0xFF)) , 0x0000f8fc, 0x00000000,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x40 ) & 0xFF)) , 0x001f01fe, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x44 ) & 0xFF)) , 0x001f01fe, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x48 ) & 0xFF)) , 0x001f01fe, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x4C ) & 0xFF)) , 0x001f01fe, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x50 ) & 0xFF)) , 0x001f01fe, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x54 ) & 0xFF)) , 0x001f01fe, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x58 ) & 0xFF)) , 0x001f01fe, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x5C ) & 0xFF)) , 0x001f01fe, 0x00000000,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x60 ) & 0xFF)) , 0xC01f01ff, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x64 ) & 0xFF)) , 0xC01f01ff, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x68 ) & 0xFF)) , 0xC01f01ff, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x6C ) & 0xFF)) , 0xC01f01ff, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x70 ) & 0xFF)) , 0xC01f01ff, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x74 ) & 0xFF)) , 0xC01f01ff, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x78 ) & 0xFF)) , 0xC01f01ff, 0x00000000,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x7C ) & 0xFF)) , 0xC01f01ff, 0x00000000,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x80 ) & 0xFF)) , 0xffff8888, 0x00000000,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x88 ) & 0xFF)) , 0xe8088008, 0x02522001 ,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x8c ) & 0xFF)) , 0xff8fe08e, (0 << 20)|(0 << 8)|(0 << 4)|(0 << 0),
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x90 ) & 0xFF)) , 0xf0000000,
+ (4 << 25)|(0 << 24)|
+ (0 << 23)|(0 << 22)|(0 << 21)|(0 << 20)|
+ (1 << 19)|(0 << 18)|(1 << 17)|(0 << 16)|
+ (2 << 14)|(0 << 13)|(0 << 12)|
+ (0 << 11)|(0 << 10)|(0 << 9)|(0 << 8)|
+ (0 << 3) |(0 << 1) |(0 << 0),
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x94 ) & 0xFF)) , 0xc180f0f0,
+ (0 << 29)|(0 << 28)|(0 << 27)|(0 << 26)|(0 << 25)|
+ (0 << 20)|(0 << 19)|(3 << 16)|(0 << 8)|(0 << 0),
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x98 ) & 0xFF)) , 0xfc00ffff, 0x00000000,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 3 ) & 0x07) << 8) | (( 0x58 ) & 0xFF)) , 0xffe0e0e0, 0x00000000,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 3 ) & 0x07) << 8) | (( 0x5C ) & 0xFF)) , 0x0000003e, 0x00000000,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 3 ) & 0x07) << 8) | (( 0x60 ) & 0xFF)) , 0xffffff00, 0x00000000,
+
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 3 ) & 0x07) << 8) | (( 0x94 ) & 0xFF)) , 0xffff8000, 0x00000f70,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 3 ) & 0x07) << 8) | (( 0x90 ) & 0xFF)) , 0xffffff80, 0x00000002,
+ ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 3 ) & 0x07) << 8) | (( 0x98 ) & 0xFF)) , 0x0000000f, 0x00068300,
+ };
+ int i;
+ int max;
+ print_debug("setting up CPU");
+ print_debug_hex8(ctrl->node_id);
+ print_debug(" northbridge registers\r\n");
+ max = sizeof(register_values)/sizeof(register_values[0]);
+ for(i = 0; i < max; i += 3) {
+ device_t dev;
+ unsigned where;
+ unsigned long reg;
+ dev = (register_values[i] & ~0xff) - ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) + ctrl->f0;
+ where = register_values[i] & 0xff;
+ reg = pci_read_config32(dev, where);
+ reg &= register_values[i+1];
+ reg |= register_values[i+2];
+ pci_write_config32(dev, where, reg);
+ }
+ print_debug("done.\r\n");
+}
+static int is_dual_channel(const struct mem_controller *ctrl)
+{
+ uint32_t dcl;
+ dcl = pci_read_config32(ctrl->f2, 0x90 );
+ return dcl & (1<<16) ;
+}
+static int is_opteron(const struct mem_controller *ctrl)
+{
+
+ uint32_t nbcap;
+ nbcap = pci_read_config32(ctrl->f3, 0xE8 );
+ return !!(nbcap & 0x0001 );
+}
+static int is_registered(const struct mem_controller *ctrl)
+{
+
+ uint32_t dcl;
+ dcl = pci_read_config32(ctrl->f2, 0x90 );
+ return !(dcl & (1<<18) );
+}
+struct dimm_size {
+ unsigned long side1;
+ unsigned long side2;
+};
+static struct dimm_size spd_get_dimm_size(unsigned device)
+{
+
+ struct dimm_size sz;
+ int value, low;
+ sz.side1 = 0;
+ sz.side2 = 0;
+
+ value = spd_read_byte(device, 3);
+ if (value < 0) goto out;
+ sz.side1 += value & 0xf;
+ value = spd_read_byte(device, 4);
+ if (value < 0) goto out;
+ sz.side1 += value & 0xf;
+ value = spd_read_byte(device, 17);
+ if (value < 0) goto out;
+ sz.side1 += log2(value & 0xff);
+
+ value = spd_read_byte(device, 7);
+ if (value < 0) goto out;
+ value &= 0xff;
+ value <<= 8;
+
+ low = spd_read_byte(device, 6);
+ if (low < 0) goto out;
+ value = value | (low & 0xff);
+ sz.side1 += log2(value);
+
+ value = spd_read_byte(device, 5);
+ if (value <= 1) goto out;
+
+ sz.side2 = sz.side1;
+ value = spd_read_byte(device, 3);
+ if (value < 0) goto out;
+ if ((value & 0xf0) == 0) goto out;
+ sz.side2 -= (value & 0x0f);
+ sz.side2 += ((value >> 4) & 0x0f);
+ value = spd_read_byte(device, 4);
+ if (value < 0) goto out;
+ sz.side2 -= (value & 0x0f);
+ sz.side2 += ((value >> 4) & 0x0f);
+ out:
+ return sz;
+}
+static void set_dimm_size(const struct mem_controller *ctrl, struct dimm_size sz, unsigned index)
+{
+ uint32_t base0, base1, map;
+ uint32_t dch;
+ if (sz.side1 != sz.side2) {
+ sz.side2 = 0;
+ }
+ map = pci_read_config32(ctrl->f2, 0x80 );
+ map &= ~(0xf << (index + 4));
+
+
+ base0 = base1 = 0;
+
+ if (sz.side1 >= (25 +3)) {
+ map |= (sz.side1 - (25 + 3)) << (index *4);
+ base0 = (1 << ((sz.side1 - (25 + 3)) + 21)) | 1;
+ }
+
+ if (sz.side2 >= (25 + 3)) {
+ base1 = (1 << ((sz.side2 - (25 + 3)) + 21)) | 1;
+ }
+
+ if (is_dual_channel(ctrl)) {
+ base0 = (base0 << 1) | (base0 & 1);
+ base1 = (base1 << 1) | (base1 & 1);
+ }
+
+ base0 &= ~0x001ffffe;
+ base1 &= ~0x001ffffe;
+
+ pci_write_config32(ctrl->f2, 0x40 + (((index << 1)+0)<<2), base0);
+ pci_write_config32(ctrl->f2, 0x40 + (((index << 1)+1)<<2), base1);
+ pci_write_config32(ctrl->f2, 0x80 , map);
+
+
+ if (base0) {
+ dch = pci_read_config32(ctrl->f2, 0x94 );
+ dch |= (1 << 26) << index;
+ pci_write_config32(ctrl->f2, 0x94 , dch);
+ }
+}
+static void spd_set_ram_size(const struct mem_controller *ctrl)
+{
+ int i;
+
+ for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
+ struct dimm_size sz;
+ sz = spd_get_dimm_size(ctrl->channel0[i]);
+ set_dimm_size(ctrl, sz, i);
+ }
+}
+static void route_dram_accesses(const struct mem_controller *ctrl,
+ unsigned long base_k, unsigned long limit_k)
+{
+
+ unsigned node_id;
+ unsigned limit;
+ unsigned base;
+ unsigned index;
+ unsigned limit_reg, base_reg;
+ device_t device;
+ node_id = ctrl->node_id;
+ index = (node_id << 3);
+ limit = (limit_k << 2);
+ limit &= 0xffff0000;
+ limit -= 0x00010000;
+ limit |= ( 0 << 8) | (node_id << 0);
+ base = (base_k << 2);
+ base &= 0xffff0000;
+ base |= (0 << 8) | (1<<1) | (1<<0);
+ limit_reg = 0x44 + index;
+ base_reg = 0x40 + index;
+ for(device = ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x7) << 8)) ; device <= ( ((( 0 ) & 0xFF) << 16) | ((( 0x1f ) & 0x1f) << 11) | ((( 1 ) & 0x7) << 8)) ; device += ( ((( 0 ) & 0xFF) << 16) | ((( 1 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ) {
+ pci_write_config32(device, limit_reg, limit);
+ pci_write_config32(device, base_reg, base);
+ }
+}
+static void set_top_mem(unsigned tom_k)
+{
+
+ if (!tom_k) {
+ set_bios_reset();
+ print_debug("No memory - reset");
+
+ pci_write_config8(( ((( 0 ) & 0xFF) << 16) | ((( 0x04 ) & 0x1f) << 11) | ((( 3 ) & 0x7) << 8)) , 0x41, 0xf1);
+
+ outb(0x0e, 0x0cf9);
+ }
+
+ print_debug("RAM: 0x");
+ print_debug_hex32(tom_k);
+ print_debug(" KB\r\n");
+
+ msr_t msr;
+ msr.lo = (tom_k & 0x003fffff) << 10;
+ msr.hi = (tom_k & 0xffc00000) >> 22;
+ wrmsr(0xC001001D , msr);
+
+ if (tom_k >= 0x003f0000) {
+ tom_k = 0x3f0000;
+ }
+ msr.lo = (tom_k & 0x003fffff) << 10;
+ msr.hi = (tom_k & 0xffc00000) >> 22;
+ wrmsr(0xC001001A , msr);
+}
+static unsigned long interleave_chip_selects(const struct mem_controller *ctrl)
+{
+
+ static const uint32_t csbase_low[] = {
+ (1 << (13 - 4)),
+ (1 << (14 - 4)),
+ (1 << (14 - 4)),
+ (1 << (15 - 4)),
+ (1 << (15 - 4)),
+ (1 << (16 - 4)),
+ (1 << (16 - 4)),
+ };
+ uint32_t csbase_inc;
+ int chip_selects, index;
+ int bits;
+ int dual_channel;
+ unsigned common_size;
+ uint32_t csbase, csmask;
+
+ chip_selects = 0;
+ common_size = 0;
+ for(index = 0; index < 8; index++) {
+ unsigned size;
+ uint32_t value;
+
+ value = pci_read_config32(ctrl->f2, 0x40 + (index << 2));
+
+
+ if (!(value & 1)) {
+ continue;
+ }
+ chip_selects++;
+ size = value >> 21;
+ if (common_size == 0) {
+ common_size = size;
+ }
+
+ if (common_size != size) {
+ return 0;
+ }
+ }
+
+ bits = log2(chip_selects);
+ if (((1 << bits) != chip_selects) || (bits < 1) || (bits > 3)) {
+ return 0;
+
+ }
+
+ if ((bits == 3) && (common_size == (1 << (32 - 3)))) {
+ print_debug("8 4GB chip selects cannot be interleaved\r\n");
+ return 0;
+ }
+
+ if (is_dual_channel(ctrl)) {
+ csbase_inc = csbase_low[log2(common_size) - 1] << 1;
+ } else {
+ csbase_inc = csbase_low[log2(common_size)];
+ }
+
+ csbase = 0 | 1;
+ csmask = (((common_size << bits) - 1) << 21);
+ csmask |= 0xfe00 & ~((csbase_inc << bits) - csbase_inc);
+ for(index = 0; index < 8; index++) {
+ uint32_t value;
+ value = pci_read_config32(ctrl->f2, 0x40 + (index << 2));
+
+ if (!(value & 1)) {
+ continue;
+ }
+ pci_write_config32(ctrl->f2, 0x40 + (index << 2), csbase);
+ pci_write_config32(ctrl->f2, 0x60 + (index << 2), csmask);
+ csbase += csbase_inc;
+ }
+
+ print_debug("Interleaved\r\n");
+
+ return common_size << (15 + bits);
+}
+static unsigned long order_chip_selects(const struct mem_controller *ctrl)
+{
+ unsigned long tom;
+
+
+ tom = 0;
+ for(;;) {
+
+ unsigned index, canidate;
+ uint32_t csbase, csmask;
+ unsigned size;
+ csbase = 0;
+ canidate = 0;
+ for(index = 0; index < 8; index++) {
+ uint32_t value;
+ value = pci_read_config32(ctrl->f2, 0x40 + (index << 2));
+
+ if (!(value & 1)) {
+ continue;
+ }
+
+
+ if (value <= csbase) {
+ continue;
+ }
+
+
+ if (tom & (1 << (index + 24))) {
+ continue;
+ }
+
+ csbase = value;
+ canidate = index;
+ }
+
+ if (csbase == 0) {
+ break;
+ }
+
+ size = csbase >> 21;
+
+ tom |= (1 << (canidate + 24));
+
+ csbase = (tom << 21) | 1;
+
+ tom += size;
+
+ csmask = ((size -1) << 21);
+ csmask |= 0xfe00;
+
+ pci_write_config32(ctrl->f2, 0x40 + (canidate << 2), csbase);
+
+ pci_write_config32(ctrl->f2, 0x60 + (canidate << 2), csmask);
+
+ }
+
+ return (tom & ~0xff000000) << 15;
+}
+static void order_dimms(const struct mem_controller *ctrl)
+{
+ unsigned long tom, tom_k, base_k;
+ unsigned node_id;
+ tom_k = interleave_chip_selects(ctrl);
+ if (!tom_k) {
+ tom_k = order_chip_selects(ctrl);
+ }
+
+ base_k = 0;
+ for(node_id = 0; node_id < ctrl->node_id; node_id++) {
+ uint32_t limit, base;
+ unsigned index;
+ index = node_id << 3;
+ base = pci_read_config32(ctrl->f1, 0x40 + index);
+
+ if ((base & 3) == 3) {
+ limit = pci_read_config32(ctrl->f1, 0x44 + index);
+ base_k = ((limit + 0x00010000) & 0xffff0000) >> 2;
+ }
+ }
+ tom_k += base_k;
+ route_dram_accesses(ctrl, base_k, tom_k);
+ set_top_mem(tom_k);
+}
+static void disable_dimm(const struct mem_controller *ctrl, unsigned index)
+{
+ print_debug("disabling dimm");
+ print_debug_hex8(index);
+ print_debug("\r\n");
+ pci_write_config32(ctrl->f2, 0x40 + (((index << 1)+0)<<2), 0);
+ pci_write_config32(ctrl->f2, 0x40 + (((index << 1)+1)<<2), 0);
+}
+static void spd_handle_unbuffered_dimms(const struct mem_controller *ctrl)
+{
+ int i;
+ int registered;
+ int unbuffered;
+ uint32_t dcl;
+ unbuffered = 0;
+ registered = 0;
+ for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
+ int value;
+ value = spd_read_byte(ctrl->channel0[i], 21);
+ if (value < 0) {
+ disable_dimm(ctrl, i);
+ continue;
+ }
+
+ if (value & (1 << 1)) {
+ registered = 1;
+ }
+
+ else {
+ unbuffered = 1;
+ }
+ }
+ if (unbuffered && registered) {
+ die("Mixed buffered and registered dimms not supported");
+ }
+ if (unbuffered && is_opteron(ctrl)) {
+ die("Unbuffered Dimms not supported on Opteron");
+ }
+ dcl = pci_read_config32(ctrl->f2, 0x90 );
+ dcl &= ~(1<<18) ;
+ if (unbuffered) {
+ dcl |= (1<<18) ;
+ }
+ pci_write_config32(ctrl->f2, 0x90 , dcl);
+}
+static void spd_enable_2channels(const struct mem_controller *ctrl)
+{
+ int i;
+ uint32_t nbcap;
+
+
+ static const unsigned addresses[] = {
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 9,
+ 11,
+ 13,
+ 17,
+ 18,
+ 21,
+ 23,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 41,
+ 42,
+ };
+ nbcap = pci_read_config32(ctrl->f3, 0xE8 );
+ if (!(nbcap & 0x0001 )) {
+ return;
+ }
+ for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
+ unsigned device0, device1;
+ int value0, value1;
+ int j;
+ device0 = ctrl->channel0[i];
+ device1 = ctrl->channel1[i];
+ if (!device1)
+ return;
+ for(j = 0; j < sizeof(addresses)/sizeof(addresses[0]); j++) {
+ unsigned addr;
+ addr = addresses[j];
+ value0 = spd_read_byte(device0, addr);
+ if (value0 < 0) {
+ break;
+ }
+ value1 = spd_read_byte(device1, addr);
+ if (value1 < 0) {
+ return;
+ }
+ if (value0 != value1) {
+ return;
+ }
+ }
+ }
+ print_debug("Enabling dual channel memory\r\n");
+ uint32_t dcl;
+ dcl = pci_read_config32(ctrl->f2, 0x90 );
+ dcl &= ~(1<<19) ;
+ dcl |= (1<<16) ;
+ pci_write_config32(ctrl->f2, 0x90 , dcl);
+}
+struct mem_param {
+ uint8_t cycle_time;
+ uint8_t divisor;
+ uint8_t tRC;
+ uint8_t tRFC;
+ uint32_t dch_memclk;
+ uint16_t dch_tref4k, dch_tref8k;
+ uint8_t dtl_twr;
+ char name[9];
+};
+static const struct mem_param *get_mem_param(unsigned min_cycle_time)
+{
+ static const struct mem_param speed[] = {
+ {
+ .name = "100Mhz\r\n",
+ .cycle_time = 0xa0,
+ .divisor = (10 <<1),
+ .tRC = 0x46,
+ .tRFC = 0x50,
+ .dch_memclk = 0 << 20 ,
+ .dch_tref4k = 0x00 ,
+ .dch_tref8k = 0x08 ,
+ .dtl_twr = 2,
+ },
+ {
+ .name = "133Mhz\r\n",
+ .cycle_time = 0x75,
+ .divisor = (7<<1)+1,
+ .tRC = 0x41,
+ .tRFC = 0x4B,
+ .dch_memclk = 2 << 20 ,
+ .dch_tref4k = 0x01 ,
+ .dch_tref8k = 0x09 ,
+ .dtl_twr = 2,
+ },
+ {
+ .name = "166Mhz\r\n",
+ .cycle_time = 0x60,
+ .divisor = (6<<1),
+ .tRC = 0x3C,
+ .tRFC = 0x48,
+ .dch_memclk = 5 << 20 ,
+ .dch_tref4k = 0x02 ,
+ .dch_tref8k = 0x0A ,
+ .dtl_twr = 3,
+ },
+ {
+ .name = "200Mhz\r\n",
+ .cycle_time = 0x50,
+ .divisor = (5<<1),
+ .tRC = 0x37,
+ .tRFC = 0x46,
+ .dch_memclk = 7 << 20 ,
+ .dch_tref4k = 0x03 ,
+ .dch_tref8k = 0x0B ,
+ .dtl_twr = 3,
+ },
+ {
+ .cycle_time = 0x00,
+ },
+ };
+ const struct mem_param *param;
+ for(param = &speed[0]; param->cycle_time ; param++) {
+ if (min_cycle_time > (param+1)->cycle_time) {
+ break;
+ }
+ }
+ if (!param->cycle_time) {
+ die("min_cycle_time to low");
+ }
+ print_debug(param->name);
+ return param;
+}
+static const struct mem_param *spd_set_memclk(const struct mem_controller *ctrl)
+{
+
+ const struct mem_param *param;
+ unsigned min_cycle_time, min_latency;
+ int i;
+ uint32_t value;
+ static const int latency_indicies[] = { 26, 23, 9 };
+ static const unsigned char min_cycle_times[] = {
+ [0 ] = 0x50,
+ [1 ] = 0x60,
+ [2 ] = 0x75,
+ [3 ] = 0xa0,
+ };
+ value = pci_read_config32(ctrl->f3, 0xE8 );
+ min_cycle_time = min_cycle_times[(value >> 5 ) & 3 ];
+ min_latency = 2;
+
+ for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
+ int new_cycle_time, new_latency;
+ int index;
+ int latencies;
+ int latency;
+
+ new_cycle_time = 0xa0;
+ new_latency = 5;
+ latencies = spd_read_byte(ctrl->channel0[i], 18);
+ if (latencies <= 0) continue;
+
+ latency = log2(latencies) -2;
+
+ for(index = 0; index < 3; index++, latency++) {
+ int value;
+ if ((latency < 2) || (latency > 4) ||
+ (!(latencies & (1 << latency)))) {
+ continue;
+ }
+ value = spd_read_byte(ctrl->channel0[i], latency_indicies[index]);
+ if (value < 0) {
+ continue;
+ }
+
+ if ((value >= min_cycle_time) && (value < new_cycle_time)) {
+ new_cycle_time = value;
+ new_latency = latency;
+ }
+ }
+ if (new_latency > 4){
+ continue;
+ }
+
+ if (new_cycle_time > min_cycle_time) {
+ min_cycle_time = new_cycle_time;
+ }
+
+ if (new_latency > min_latency) {
+ min_latency = new_latency;
+ }
+ }
+
+
+ for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
+ int latencies;
+ int latency;
+ int index;
+ int value;
+ int dimm;
+ latencies = spd_read_byte(ctrl->channel0[i], 18);
+ if (latencies <= 0) {
+ goto dimm_err;
+ }
+
+ latency = log2(latencies) -2;
+
+ for(index = 0; index < 3; index++, latency++) {
+ if (!(latencies & (1 << latency))) {
+ continue;
+ }
+ if (latency == min_latency)
+ break;
+ }
+
+ if ((latency != min_latency) || (index >= 3)) {
+ goto dimm_err;
+ }
+
+
+ value = spd_read_byte(ctrl->channel0[i], latency_indicies[index]);
+
+
+ if (value <= min_cycle_time) {
+ continue;
+ }
+
+ dimm_err:
+ disable_dimm(ctrl, i);
+ }
+
+ param = get_mem_param(min_cycle_time);
+
+ value = pci_read_config32(ctrl->f2, 0x94 );
+ value &= ~(0x7 << 20 );
+ value |= param->dch_memclk;
+ pci_write_config32(ctrl->f2, 0x94 , value);
+ static const unsigned latencies[] = { 1 , 5 , 2 };
+
+ value = pci_read_config32(ctrl->f2, 0x88 );
+ value &= ~(0x7 << 0 );
+ value |= latencies[min_latency - 2] << 0 ;
+ pci_write_config32(ctrl->f2, 0x88 , value);
+
+ return param;
+}
+static int update_dimm_Trc(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+ unsigned clocks, old_clocks;
+ uint32_t dtl;
+ int value;
+ value = spd_read_byte(ctrl->channel0[i], 41);
+ if (value < 0) return -1;
+ if ((value == 0) || (value == 0xff)) {
+ value = param->tRC;
+ }
+ clocks = ((value << 1) + param->divisor - 1)/param->divisor;
+ if (clocks < 7 ) {
+ clocks = 7 ;
+ }
+ if (clocks > 22 ) {
+ return -1;
+ }
+ dtl = pci_read_config32(ctrl->f2, 0x88 );
+ old_clocks = ((dtl >> 4 ) & 0xf ) + 7 ;
+ if (old_clocks > clocks) {
+ clocks = old_clocks;
+ }
+ dtl &= ~(0xf << 4 );
+ dtl |= ((clocks - 7 ) << 4 );
+ pci_write_config32(ctrl->f2, 0x88 , dtl);
+ return 0;
+}
+static int update_dimm_Trfc(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+ unsigned clocks, old_clocks;
+ uint32_t dtl;
+ int value;
+ value = spd_read_byte(ctrl->channel0[i], 42);
+ if (value < 0) return -1;
+ if ((value == 0) || (value == 0xff)) {
+ value = param->tRFC;
+ }
+ clocks = ((value << 1) + param->divisor - 1)/param->divisor;
+ if (clocks < 9 ) {
+ clocks = 9 ;
+ }
+ if (clocks > 24 ) {
+ return -1;
+ }
+ dtl = pci_read_config32(ctrl->f2, 0x88 );
+ old_clocks = ((dtl >> 8 ) & 0xf ) + 9 ;
+ if (old_clocks > clocks) {
+ clocks = old_clocks;
+ }
+ dtl &= ~(0xf << 8 );
+ dtl |= ((clocks - 9 ) << 8 );
+ pci_write_config32(ctrl->f2, 0x88 , dtl);
+ return 0;
+}
+static int update_dimm_Trcd(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+ unsigned clocks, old_clocks;
+ uint32_t dtl;
+ int value;
+ value = spd_read_byte(ctrl->channel0[i], 29);
+ if (value < 0) return -1;
+ clocks = (value + ((param->divisor & 0xff) << 1) -1)/((param->divisor & 0xff) << 1);
+ if (clocks < 2 ) {
+ clocks = 2 ;
+ }
+ if (clocks > 6 ) {
+ return -1;
+ }
+ dtl = pci_read_config32(ctrl->f2, 0x88 );
+ old_clocks = ((dtl >> 12 ) & 0x7 ) + 0 ;
+ if (old_clocks > clocks) {
+ clocks = old_clocks;
+ }
+ dtl &= ~(0x7 << 12 );
+ dtl |= ((clocks - 0 ) << 12 );
+ pci_write_config32(ctrl->f2, 0x88 , dtl);
+ return 0;
+}
+static int update_dimm_Trrd(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+ unsigned clocks, old_clocks;
+ uint32_t dtl;
+ int value;
+ value = spd_read_byte(ctrl->channel0[i], 28);
+ if (value < 0) return -1;
+ clocks = (value + ((param->divisor & 0xff) << 1) -1)/((param->divisor & 0xff) << 1);
+ if (clocks < 2 ) {
+ clocks = 2 ;
+ }
+ if (clocks > 4 ) {
+ return -1;
+ }
+ dtl = pci_read_config32(ctrl->f2, 0x88 );
+ old_clocks = ((dtl >> 16 ) & 0x7 ) + 0 ;
+ if (old_clocks > clocks) {
+ clocks = old_clocks;
+ }
+ dtl &= ~(0x7 << 16 );
+ dtl |= ((clocks - 0 ) << 16 );
+ pci_write_config32(ctrl->f2, 0x88 , dtl);
+ return 0;
+}
+static int update_dimm_Tras(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+ unsigned clocks, old_clocks;
+ uint32_t dtl;
+ int value;
+ value = spd_read_byte(ctrl->channel0[i], 30);
+ if (value < 0) return -1;
+ clocks = ((value << 1) + param->divisor - 1)/param->divisor;
+ if (clocks < 5 ) {
+ clocks = 5 ;
+ }
+ if (clocks > 15 ) {
+ return -1;
+ }
+ dtl = pci_read_config32(ctrl->f2, 0x88 );
+ old_clocks = ((dtl >> 20 ) & 0xf ) + 0 ;
+ if (old_clocks > clocks) {
+ clocks = old_clocks;
+ }
+ dtl &= ~(0xf << 20 );
+ dtl |= ((clocks - 0 ) << 20 );
+ pci_write_config32(ctrl->f2, 0x88 , dtl);
+ return 0;
+}
+static int update_dimm_Trp(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+ unsigned clocks, old_clocks;
+ uint32_t dtl;
+ int value;
+ value = spd_read_byte(ctrl->channel0[i], 27);
+ if (value < 0) return -1;
+ clocks = (value + ((param->divisor & 0xff) << 1) - 1)/((param->divisor & 0xff) << 1);
+ if (clocks < 2 ) {
+ clocks = 2 ;
+ }
+ if (clocks > 6 ) {
+ return -1;
+ }
+ dtl = pci_read_config32(ctrl->f2, 0x88 );
+ old_clocks = ((dtl >> 24 ) & 0x7 ) + 0 ;
+ if (old_clocks > clocks) {
+ clocks = old_clocks;
+ }
+ dtl &= ~(0x7 << 24 );
+ dtl |= ((clocks - 0 ) << 24 );
+ pci_write_config32(ctrl->f2, 0x88 , dtl);
+ return 0;
+}
+static void set_Twr(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+ uint32_t dtl;
+ dtl = pci_read_config32(ctrl->f2, 0x88 );
+ dtl &= ~(0x1 << 28 );
+ dtl |= (param->dtl_twr - 2 ) << 28 ;
+ pci_write_config32(ctrl->f2, 0x88 , dtl);
+}
+static void init_Tref(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+ uint32_t dth;
+ dth = pci_read_config32(ctrl->f2, 0x8c );
+ dth &= ~(0x1f << 8 );
+ dth |= (param->dch_tref4k << 8 );
+ pci_write_config32(ctrl->f2, 0x8c , dth);
+}
+static int update_dimm_Tref(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+ uint32_t dth;
+ int value;
+ unsigned tref, old_tref;
+ value = spd_read_byte(ctrl->channel0[i], 3);
+ if (value < 0) return -1;
+ value &= 0xf;
+ tref = param->dch_tref8k;
+ if (value == 12) {
+ tref = param->dch_tref4k;
+ }
+ dth = pci_read_config32(ctrl->f2, 0x8c );
+ old_tref = (dth >> 8 ) & 0x1f ;
+ if ((value == 12) && (old_tref == param->dch_tref4k)) {
+ tref = param->dch_tref4k;
+ } else {
+ tref = param->dch_tref8k;
+ }
+ dth &= ~(0x1f << 8 );
+ dth |= (tref << 8 );
+ pci_write_config32(ctrl->f2, 0x8c , dth);
+ return 0;
+}
+static int update_dimm_x4(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+ uint32_t dcl;
+ int value;
+ int dimm;
+ value = spd_read_byte(ctrl->channel0[i], 13);
+ if (value < 0) {
+ return -1;
+ }
+ dimm = i;
+ dimm += 20 ;
+ dcl = pci_read_config32(ctrl->f2, 0x90 );
+ dcl &= ~(1 << dimm);
+ if (value == 4) {
+ dcl |= (1 << dimm);
+ }
+ pci_write_config32(ctrl->f2, 0x90 , dcl);
+ return 0;
+}
+static int update_dimm_ecc(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+ uint32_t dcl;
+ int value;
+ value = spd_read_byte(ctrl->channel0[i], 11);
+ if (value < 0) {
+ return -1;
+ }
+ if (value != 2) {
+ dcl = pci_read_config32(ctrl->f2, 0x90 );
+ dcl &= ~(1<<17) ;
+ pci_write_config32(ctrl->f2, 0x90 , dcl);
+ }
+ return 0;
+}
+static int count_dimms(const struct mem_controller *ctrl)
+{
+ int dimms;
+ unsigned index;
+ dimms = 0;
+ for(index = 0; index < 8; index += 2) {
+ uint32_t csbase;
+ csbase = pci_read_config32(ctrl->f2, (0x40 + index << 2));
+ if (csbase & 1) {
+ dimms += 1;
+ }
+ }
+ return dimms;
+}
+static void set_Twtr(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+ uint32_t dth;
+ unsigned clocks;
+ clocks = 1;
+ dth = pci_read_config32(ctrl->f2, 0x8c );
+ dth &= ~(0x1 << 0 );
+ dth |= ((clocks - 1 ) << 0 );
+ pci_write_config32(ctrl->f2, 0x8c , dth);
+}
+static void set_Trwt(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+ uint32_t dth, dtl;
+ unsigned divisor;
+ unsigned latency;
+ unsigned clocks;
+ clocks = 0;
+ dtl = pci_read_config32(ctrl->f2, 0x88 );
+ latency = (dtl >> 0 ) & 0x7 ;
+ divisor = param->divisor;
+ if (is_opteron(ctrl)) {
+ if (latency == 1 ) {
+ if (divisor == ((6 << 0) + 0)) {
+
+ clocks = 3;
+ }
+ else if (divisor > ((6 << 0)+0)) {
+
+ clocks = 2;
+ }
+ }
+ else if (latency == 5 ) {
+ clocks = 3;
+ }
+ else if (latency == 2 ) {
+ if (divisor == ((6 << 0)+0)) {
+
+ clocks = 4;
+ }
+ else if (divisor > ((6 << 0)+0)) {
+
+ clocks = 3;
+ }
+ }
+ }
+ else {
+ if (is_registered(ctrl)) {
+ if (latency == 1 ) {
+ clocks = 2;
+ }
+ else if (latency == 5 ) {
+ clocks = 3;
+ }
+ else if (latency == 2 ) {
+ clocks = 3;
+ }
+ }
+ else {
+ if (latency == 1 ) {
+ clocks = 3;
+ }
+ else if (latency == 5 ) {
+ clocks = 4;
+ }
+ else if (latency == 2 ) {
+ clocks = 4;
+ }
+ }
+ }
+ if ((clocks < 1 ) || (clocks > 6 )) {
+ die("Unknown Trwt");
+ }
+
+ dth = pci_read_config32(ctrl->f2, 0x8c );
+ dth &= ~(0x7 << 4 );
+ dth |= ((clocks - 1 ) << 4 );
+ pci_write_config32(ctrl->f2, 0x8c , dth);
+ return;
+}
+static void set_Twcl(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+
+ uint32_t dth;
+ unsigned clocks;
+ if (is_registered(ctrl)) {
+ clocks = 2;
+ } else {
+ clocks = 1;
+ }
+ dth = pci_read_config32(ctrl->f2, 0x8c );
+ dth &= ~(0x7 << 20 );
+ dth |= ((clocks - 1 ) << 20 );
+ pci_write_config32(ctrl->f2, 0x8c , dth);
+}
+static void set_read_preamble(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+ uint32_t dch;
+ unsigned divisor;
+ unsigned rdpreamble;
+ divisor = param->divisor;
+ dch = pci_read_config32(ctrl->f2, 0x94 );
+ dch &= ~(0xf << 8 );
+ rdpreamble = 0;
+ if (is_registered(ctrl)) {
+ if (divisor == ((10 << 1)+0)) {
+
+ rdpreamble = ((9 << 1)+ 0);
+ }
+ else if (divisor == ((7 << 1)+1)) {
+
+ rdpreamble = ((8 << 1)+0);
+ }
+ else if (divisor == ((6 << 1)+0)) {
+
+ rdpreamble = ((7 << 1)+1);
+ }
+ else if (divisor == ((5 << 1)+0)) {
+
+ rdpreamble = ((7 << 1)+0);
+ }
+ }
+ else {
+ int slots;
+ int i;
+ slots = 0;
+ for(i = 0; i < 4; i++) {
+ if (ctrl->channel0[i]) {
+ slots += 1;
+ }
+ }
+ if (divisor == ((10 << 1)+0)) {
+
+ if (slots <= 2) {
+
+ rdpreamble = ((9 << 1)+0);
+ } else {
+
+ rdpreamble = ((14 << 1)+0);
+ }
+ }
+ else if (divisor == ((7 << 1)+1)) {
+
+ if (slots <= 2) {
+
+ rdpreamble = ((7 << 1)+0);
+ } else {
+
+ rdpreamble = ((11 << 1)+0);
+ }
+ }
+ else if (divisor == ((6 << 1)+0)) {
+
+ if (slots <= 2) {
+
+ rdpreamble = ((7 << 1)+0);
+ } else {
+
+ rdpreamble = ((9 << 1)+0);
+ }
+ }
+ else if (divisor == ((5 << 1)+0)) {
+
+ if (slots <= 2) {
+
+ rdpreamble = ((5 << 1)+0);
+ } else {
+
+ rdpreamble = ((7 << 1)+0);
+ }
+ }
+ }
+ if ((rdpreamble < ((2<<1)+0) ) || (rdpreamble > ((9<<1)+1) )) {
+ die("Unknown rdpreamble");
+ }
+ dch |= (rdpreamble - ((2<<1)+0) ) << 8 ;
+ pci_write_config32(ctrl->f2, 0x94 , dch);
+}
+static void set_max_async_latency(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+ uint32_t dch;
+ int i;
+ unsigned async_lat;
+ int dimms;
+ dimms = count_dimms(ctrl);
+ dch = pci_read_config32(ctrl->f2, 0x94 );
+ dch &= ~(0xf << 0 );
+ async_lat = 0;
+ if (is_registered(ctrl)) {
+ if (dimms == 4) {
+
+ async_lat = 9;
+ }
+ else {
+
+ async_lat = 8;
+ }
+ }
+ else {
+ if (dimms > 3) {
+ die("Too many unbuffered dimms");
+ }
+ else if (dimms == 3) {
+
+ async_lat = 7;
+ }
+ else {
+
+ async_lat = 6;
+ }
+ }
+ dch |= ((async_lat - 0 ) << 0 );
+ pci_write_config32(ctrl->f2, 0x94 , dch);
+}
+static void set_idle_cycle_limit(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+ uint32_t dch;
+
+ dch = pci_read_config32(ctrl->f2, 0x94 );
+ dch &= ~(0x7 << 16 );
+ dch |= 3 << 16 ;
+ dch |= (1 << 19) ;
+ pci_write_config32(ctrl->f2, 0x94 , dch);
+}
+static void spd_set_dram_timing(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+ int dimms;
+ int i;
+ int rc;
+
+ init_Tref(ctrl, param);
+ for(i = 0; (i < 4) && ctrl->channel0[i]; i++) {
+ int rc;
+
+ if (update_dimm_Trc (ctrl, param, i) < 0) goto dimm_err;
+ if (update_dimm_Trfc(ctrl, param, i) < 0) goto dimm_err;
+ if (update_dimm_Trcd(ctrl, param, i) < 0) goto dimm_err;
+ if (update_dimm_Trrd(ctrl, param, i) < 0) goto dimm_err;
+ if (update_dimm_Tras(ctrl, param, i) < 0) goto dimm_err;
+ if (update_dimm_Trp (ctrl, param, i) < 0) goto dimm_err;
+
+ if (update_dimm_Tref(ctrl, param, i) < 0) goto dimm_err;
+
+ if (update_dimm_x4 (ctrl, param, i) < 0) goto dimm_err;
+ if (update_dimm_ecc(ctrl, param, i) < 0) goto dimm_err;
+ continue;
+ dimm_err:
+ disable_dimm(ctrl, i);
+
+ }
+
+ set_Twr(ctrl, param);
+
+ set_Twtr(ctrl, param);
+ set_Trwt(ctrl, param);
+ set_Twcl(ctrl, param);
+
+ set_read_preamble(ctrl, param);
+ set_max_async_latency(ctrl, param);
+ set_idle_cycle_limit(ctrl, param);
+}
+static void sdram_set_spd_registers(const struct mem_controller *ctrl)
+{
+ const struct mem_param *param;
+ spd_enable_2channels(ctrl);
+ spd_set_ram_size(ctrl);
+ spd_handle_unbuffered_dimms(ctrl);
+ param = spd_set_memclk(ctrl);
+ spd_set_dram_timing(ctrl, param);
+ order_dimms(ctrl);
+}
+static void sdram_enable(int controllers, const struct mem_controller *ctrl)
+{
+ int i;
+
+ for(i = 0; i < controllers; i++) {
+ uint32_t dch;
+ dch = pci_read_config32(ctrl[i].f2, 0x94 );
+ dch |= (1 << 25) ;
+ pci_write_config32(ctrl[i].f2, 0x94 , dch);
+ }
+
+ memreset(controllers, ctrl);
+ for(i = 0; i < controllers; i++) {
+ uint32_t dcl;
+
+ dcl = pci_read_config32(ctrl[i].f2, 0x90 );
+ if (dcl & (1<<17) ) {
+ uint32_t mnc;
+ print_debug("ECC enabled\r\n");
+ mnc = pci_read_config32(ctrl[i].f3, 0x44 );
+ mnc |= (1 << 22) ;
+ if (dcl & (1<<16) ) {
+ mnc |= (1 << 23) ;
+ }
+ pci_write_config32(ctrl[i].f3, 0x44 , mnc);
+ }
+ dcl |= (1<<3) ;
+ pci_write_config32(ctrl[i].f2, 0x90 , dcl);
+ dcl &= ~(1<<3) ;
+ dcl &= ~(1<<0) ;
+ dcl &= ~(1<<1) ;
+ dcl &= ~(1<<2) ;
+ dcl |= (1<<8) ;
+ pci_write_config32(ctrl[i].f2, 0x90 , dcl);
+ }
+ for(i = 0; i < controllers; i++) {
+ uint32_t dcl;
+ print_debug("Initializing memory: ");
+ int loops = 0;
+ do {
+ dcl = pci_read_config32(ctrl[i].f2, 0x90 );
+ loops += 1;
+ if ((loops & 1023) == 0) {
+ print_debug(".");
+ }
+ } while(((dcl & (1<<8) ) != 0) && (loops < 300000 ));
+ if (loops >= 300000 ) {
+ print_debug(" failed\r\n");
+ } else {
+ print_debug(" done\r\n");
+ }
+ if (dcl & (1<<17) ) {
+ print_debug("Clearing memory: ");
+ if (!is_cpu_pre_c0()) {
+
+ dcl &= ~((1<<11) | (1<<10) );
+ pci_write_config32(ctrl[i].f2, 0x90 , dcl);
+ do {
+ dcl = pci_read_config32(ctrl[i].f2, 0x90 );
+ } while(((dcl & (1<<11) ) == 0) || ((dcl & (1<<10) ) == 0) );
+ }
+ uint32_t base, last_scrub_k, scrub_k;
+ uint32_t cnt,zstart,zend;
+ msr_t msr,msr_201;
+
+ pci_write_config32(ctrl[i].f3, 0x58 ,
+ (0 << 16) | (0 << 8) | (0 << 0));
+
+ msr_201 = rdmsr(0x201);
+ zstart = pci_read_config32(ctrl[0].f1, 0x40 + (i*8));
+ zend = pci_read_config32(ctrl[0].f1, 0x44 + (i*8));
+ zstart >>= 16;
+ zend >>=16;
+ print_debug("addr ");
+ print_debug_hex32(zstart);
+ print_debug("-");
+ print_debug_hex32(zend);
+ print_debug("\r\n");
+
+
+ msr = rdmsr(0x2ff );
+ msr.lo &= ~(1<<10);
+ wrmsr(0x2ff , msr);
+
+ msr = rdmsr(0xc0010015);
+ msr.lo |= (1<<17);
+ wrmsr(0xc0010015,msr);
+ for(;zstart<zend;zstart+=4) {
+
+ if(zstart == 0x0fc)
+ continue;
+
+
+ __asm__ volatile(
+ "movl %%cr0, %0\n\t"
+ "orl $0x40000000, %0\n\t"
+ "movl %0, %%cr0\n\t"
+ :"=r" (cnt)
+ );
+
+
+ msr.lo = 1 + ((zstart&0x0ff)<<24);
+ msr.hi = (zstart&0x0ff00)>>8;
+ wrmsr(0x200,msr);
+
+ msr.hi = 0x000000ff;
+ msr.lo = 0xfc000800;
+ wrmsr(0x201,msr);
+
+ __asm__ volatile(
+ "movl %%cr0, %0\n\t"
+ "andl $0x9fffffff, %0\n\t"
+ "movl %0, %%cr0\n\t"
+ :"=r" (cnt)
+ );
+
+ msr.lo = (zstart&0xff) << 24;
+ msr.hi = (zstart&0xff00) >> 8;
+ wrmsr(0xc0000100,msr);
+ print_debug_char((zstart > 0x0ff)?'+':'-');
+
+
+ __asm__ volatile(
+ "1: \n\t"
+ "movl %0, %%fs:(%1)\n\t"
+ "addl $4,%1\n\t"
+ "subl $1,%2\n\t"
+ "jnz 1b\n\t"
+ :
+ : "a" (0), "D" (0), "c" (0x01000000)
+ );
+ }
+
+
+ __asm__ volatile(
+ "movl %%cr0, %0\n\t"
+ "orl $0x40000000, %0\n\t"
+ "movl %0, %%cr0\n\t"
+ :"=r" (cnt)
+ );
+
+
+ msr = rdmsr(0x2ff );
+ msr.lo |= 0x0400;
+ wrmsr(0x2ff , msr);
+
+ msr.lo = 6;
+ msr.hi = 0;
+ wrmsr(0x200,msr);
+ wrmsr(0x201,msr_201);
+
+ msr.lo = 0;
+ msr.hi = 0;
+ wrmsr(0xc0000100,msr);
+
+ __asm__ volatile(
+ "movl %%cr0, %0\n\t"
+ "andl $0x9fffffff, %0\n\t"
+ "movl %0, %%cr0\n\t"
+ :"=r" (cnt)
+ );
+
+
+ msr = rdmsr(0xc0010015);
+ msr.lo &= ~(1<<17);
+ wrmsr(0xc0010015,msr);
+
+ base = pci_read_config32(ctrl[i].f1, 0x40 + (ctrl[i].node_id << 3));
+ base &= 0xffff0000;
+
+ pci_write_config32(ctrl[i].f3, 0x5C , base << 8);
+ pci_write_config32(ctrl[i].f3, 0x60 , base >> 24);
+
+ pci_write_config32(ctrl[i].f3, 0x58 ,
+ (22 << 16) | (22 << 8) | (22 << 0));
+ print_debug("done\r\n");
+ }
+ }
+}
+
+
+
+
+
+typedef uint8_t u8;
+typedef uint32_t u32;
+typedef int8_t bool;
+static void disable_probes(void)
+{
+
+
+ u32 val;
+ print_debug("Disabling read/write/fill probes for UP... ");
+ val=pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x68);
+ val |= (1<<10)|(1<<9)|(1<<8)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1 << 0);
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x68, val);
+ print_debug("done.\r\n");
+}
+
+static void wait_ap_stop(u8 node)
+{
+ unsigned long reg;
+ unsigned long i;
+ for(i=0;i< 1000 ;i++) {
+ unsigned long regx;
+ regx = pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ,0x6c);
+ if((regx & (1<<4))==1) break;
+ }
+ reg = pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ,0x6c);
+ reg &= ~(1<<4);
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x6c, reg);
+}
+static void notify_bsp_ap_is_stopped(void)
+{
+ unsigned long reg;
+ unsigned long apic_id;
+ apic_id = *((volatile unsigned long *)(0xfee00000 + 0x020 ));
+ apic_id >>= 24;
+
+ if(apic_id != 0) {
+
+ reg = pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ apic_id ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x6C);
+ reg |= 1<<4;
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ apic_id ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x6C, reg);
+ }
+
+}
+
+static void enable_routing(u8 node)
+{
+ u32 val;
+
+
+ print_debug("Enabling routing table for node ");
+ print_debug_hex32(node);
+ val=pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x6c);
+ val &= ~((1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0));
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x6c, val);
+
+ if(node!=0) {
+ wait_ap_stop(node);
+ }
+
+ print_debug(" done.\r\n");
+}
+static void rename_temp_node(u8 node)
+{
+ uint32_t val;
+ print_debug("Renaming current temp node to ");
+ print_debug_hex32(node);
+ val=pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ 7 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x60);
+ val &= (~7);
+ val |= node;
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ 7 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x60, val);
+ print_debug(" done.\r\n");
+}
+static bool check_connection(u8 src, u8 dest, u8 link)
+{
+
+ u32 val;
+
+
+ val=pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ src ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x98+link);
+ if ( (val&0x17) != 0x03)
+ return 0;
+
+ val=pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ dest ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ,0);
+ if(val != 0x11001022)
+ return 0;
+ return 1;
+}
+static void optimize_connection(u8 node1, u8 link1, u8 node2, u8 link2)
+{
+ static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
+ static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
+ uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask;
+ uint8_t width_cap1, width_cap2, width_cap, width, ln_width1, ln_width2;
+ uint8_t freq;
+
+
+ freq_cap1 = pci_read_config16(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node1 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x80 + link1 + 0x0a );
+ freq_cap2 = pci_read_config16(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node2 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x80 + link2 + 0x0a );
+
+
+ freq = log2(freq_cap1 & freq_cap2 & 0xff);
+
+ pci_write_config8(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node1 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x80 + link1 + 0x09 , freq);
+ pci_write_config8(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node2 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x80 + link2 + 0x09 , freq);
+
+ width_cap1 = pci_read_config8(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node1 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x80 + link1 + 6 );
+ width_cap2 = pci_read_config8(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node2 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x80 + link2 + 6 );
+
+ ln_width1 = link_width_to_pow2[width_cap1 & 7];
+ ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
+ if (ln_width1 > ln_width2) {
+ ln_width1 = ln_width2;
+ }
+ width = pow2_to_link_width[ln_width1];
+
+ ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
+ ln_width2 = link_width_to_pow2[width_cap2 & 7];
+ if (ln_width1 > ln_width2) {
+ ln_width1 = ln_width2;
+ }
+ width |= pow2_to_link_width[ln_width1] << 4;
+
+
+ pci_write_config8(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node1 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x80 + link1 + 6 + 1, width);
+
+ width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
+ pci_write_config8(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node2 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x80 + link2 + 6 + 1, width);
+}
+static void fill_row(u8 node, u8 row, u32 value)
+{
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x40+(row<<2), value);
+}
+static void setup_row(u8 source, u8 dest, u8 cpus)
+{
+ fill_row(source,dest,generate_row(source,dest,cpus));
+}
+static void setup_temp_row(u8 source, u8 dest, u8 cpus)
+{
+ fill_row(source,7,((generate_row( source,dest,cpus )&(~0x0f0000))|0x010000) );
+}
+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;
+ print_debug("setup_remote_node\r\n");
+ for(row=0; row<cpus; row++)
+ setup_remote_row(node, row, cpus);
+
+ for(i = 0; i < sizeof(pci_reg)/sizeof(pci_reg[0]); i++) {
+ uint32_t value;
+ uint8_t reg;
+ reg = pci_reg[i];
+ value = pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ 0 ) & 0x1f) << 11) | ((( 1 ) & 0x7) << 8)) , reg);
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ 7 ) & 0x1f) << 11) | ((( 1 ) & 0x7) << 8)) , reg, value);
+ }
+ print_debug("setup_remote_done\r\n");
+}
+static u8 setup_uniprocessor(void)
+{
+ print_debug("Enabling UP settings\r\n");
+ disable_probes();
+ return 1;
+}
+static u8 setup_smp(void)
+{
+ u8 cpus=2;
+ print_debug("Enabling SMP settings\r\n");
+ setup_row(0,0,cpus);
+
+ setup_temp_row(0,1,cpus);
+
+ if (!check_connection(0, 7, 0x20 )) {
+ print_debug("No connection to Node 1.\r\n");
+ fill_row( 0 ,7,0x00010101 ) ;
+ setup_uniprocessor();
+ return 1;
+ }
+
+ optimize_connection(0, 0x20 , 7, 0x20 );
+ setup_node(0, cpus);
+ setup_remote_node(1, cpus);
+ rename_temp_node(1);
+ enable_routing(1);
+
+ fill_row( 0 ,7,0x00010101 ) ;
+
+ print_debug_hex32(cpus);
+ print_debug(" nodes initialized.\r\n");
+ return cpus;
+}
+static unsigned detect_mp_capabilities(unsigned cpus)
+{
+ unsigned node, row, mask;
+ bool mp_cap= (-1) ;
+ print_debug("detect_mp_capabilities: ");
+ print_debug_hex32(cpus);
+ print_debug("\r\n");
+ if (cpus>2)
+ mask=0x06;
+ else
+ mask=0x02;
+ for (node=0; node<cpus; node++) {
+ if ((pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node ) & 0x1f) << 11) | ((( 3 ) & 0x7) << 8)) , 0xe8) & mask)!=mask)
+ mp_cap= (0) ;
+ }
+ if (mp_cap)
+ return cpus;
+
+ 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(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node-1 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , row-1, 0x00010101 );
+
+ return setup_uniprocessor();
+}
+static void coherent_ht_finalize(unsigned cpus)
+{
+ int node;
+ bool rev_a0;
+
+
+ print_debug("coherent_ht_finalize\r\n");
+ rev_a0= is_cpu_rev_a0();
+ for (node=0; node<cpus; node++) {
+ u32 val;
+ val=pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x60);
+ val &= (~0x000F0070);
+ val |= ((cpus-1)<<16)|((cpus-1)<<4);
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ,0x60,val);
+ val=pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x68);
+ val |= 0x00008000;
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ,0x68,val);
+ if (rev_a0) {
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ,0x94,0);
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ,0xb4,0);
+ pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24+ node ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ,0xd4,0);
+ }
+ }
+ print_debug("done\r\n");
+}
+static int setup_coherent_ht_domain(void)
+{
+ unsigned cpus;
+ int reset_needed = 0;
+ enable_routing(0) ;
+ cpus=setup_smp();
+ cpus=detect_mp_capabilities(cpus);
+ coherent_ht_finalize(cpus);
+
+ coherent_ht_mainboard(cpus);
+ return reset_needed;
+}
+void sdram_no_memory(void)
+{
+ print_err("No memory!!\r\n");
+ while(1) {
+ hlt();
+ }
+}
+
+void sdram_initialize(int controllers, const struct mem_controller *ctrl)
+{
+ int i;
+
+ for(i = 0; i < controllers; i++) {
+ print_debug("Ram1.");
+ print_debug_hex8(i);
+ print_debug("\r\n");
+ sdram_set_registers(ctrl + i);
+ }
+
+ for(i = 0; i < controllers; i++) {
+ print_debug("Ram2.");
+ print_debug_hex8(i);
+ print_debug("\r\n");
+ sdram_set_spd_registers(ctrl + i);
+ }
+
+ print_debug("Ram3\r\n");
+ sdram_enable(controllers, ctrl);
+ print_debug("Ram4\r\n");
+}
+static void enable_lapic(void)
+{
+ msr_t msr;
+ msr = rdmsr(0x1b);
+ msr.hi &= 0xffffff00;
+ msr.lo &= 0x000007ff;
+ msr.lo |= 0xfee00000 | (1 << 11);
+ wrmsr(0x1b, msr);
+}
+static void stop_this_cpu(void)
+{
+ unsigned apicid;
+ apicid = apic_read(0x020 ) >> 24;
+
+ apic_write(0x310 , (( apicid )<<24) );
+ apic_write(0x300 , 0x08000 | 0x04000 | 0x00500 );
+
+ apic_wait_icr_idle();
+
+ apic_write(0x310 , (( apicid )<<24) );
+ apic_write(0x300 , 0x08000 | 0x00500 );
+
+ apic_wait_icr_idle();
+
+ for(;;) {
+ hlt();
+ }
+}
+static void pc87360_enable_serial(void)
+{
+ pnp_set_logical_device(0x2e , 0x03 );
+ pnp_set_enable(0x2e , 1);
+ pnp_set_iobase0(0x2e , 0x3f8);
+}
+static void main(void)
+{
+
+ static const struct mem_controller cpu[] = {
+ {
+ .node_id = 0,
+ .f0 = ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ,
+ .f1 = ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x7) << 8)) ,
+ .f2 = ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x7) << 8)) ,
+ .f3 = ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 3 ) & 0x7) << 8)) ,
+ .channel0 = { (0xa<<3)|0, (0xa<<3)|2, 0, 0 },
+ .channel1 = { (0xa<<3)|1, (0xa<<3)|3, 0, 0 },
+ },
+ {
+ .node_id = 1,
+ .f0 = ( ((( 0 ) & 0xFF) << 16) | ((( 0x19 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ,
+ .f1 = ( ((( 0 ) & 0xFF) << 16) | ((( 0x19 ) & 0x1f) << 11) | ((( 1 ) & 0x7) << 8)) ,
+ .f2 = ( ((( 0 ) & 0xFF) << 16) | ((( 0x19 ) & 0x1f) << 11) | ((( 2 ) & 0x7) << 8)) ,
+ .f3 = ( ((( 0 ) & 0xFF) << 16) | ((( 0x19 ) & 0x1f) << 11) | ((( 3 ) & 0x7) << 8)) ,
+ .channel0 = { (0xa<<3)|4, (0xa<<3)|6, 0, 0 },
+ .channel1 = { (0xa<<3)|5, (0xa<<3)|7, 0, 0 },
+ },
+ };
+ if (cpu_init_detected()) {
+ asm("jmp __cpu_reset");
+ }
+ enable_lapic();
+ init_timer();
+ if (!boot_cpu()) {
+ stop_this_cpu();
+ }
+ pc87360_enable_serial();
+ uart_init();
+ console_init();
+ setup_default_resource_map();
+ setup_coherent_ht_domain();
+ enumerate_ht_chain(0);
+ distinguish_cpu_resets(0);
+
+ enable_smbus();
+ memreset_setup();
+ sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
+
+}
diff --git a/util/romcc/tests/simple_test57.c b/util/romcc/tests/simple_test57.c
new file mode 100644
index 0000000000..47e2397f17
--- /dev/null
+++ b/util/romcc/tests/simple_test57.c
@@ -0,0 +1,5 @@
+static void main(void)
+{
+ for(;;) {
+ }
+}
diff --git a/util/romcc/tests/simple_test58.c b/util/romcc/tests/simple_test58.c
new file mode 100644
index 0000000000..a5cd52171c
--- /dev/null
+++ b/util/romcc/tests/simple_test58.c
@@ -0,0 +1,9 @@
+static void main(void)
+{
+ const char *str;
+ unsigned char ch;
+ str = "one\r\n";
+ while((ch = *str++) != '\0') {
+ __builtin_outb(ch, 0x3f0);
+ }
+}
diff --git a/util/romcc/tests/simple_test60.c b/util/romcc/tests/simple_test60.c
index 55a5f19389..d277c94dd3 100644
--- a/util/romcc/tests/simple_test60.c
+++ b/util/romcc/tests/simple_test60.c
@@ -3,7 +3,7 @@ struct mem_param {
unsigned char divisor;
unsigned char tRC;
unsigned char tRFC;
- unsigned dch_memclk;
+ unsigned dch_memclk;
unsigned short dch_tref4k, dch_tref8k;
unsigned char dtl_twr;
char name[9];
diff --git a/util/romcc/tests/simple_test61.c b/util/romcc/tests/simple_test61.c
new file mode 100644
index 0000000000..583a9db36b
--- /dev/null
+++ b/util/romcc/tests/simple_test61.c
@@ -0,0 +1,26 @@
+static void spd_set_nbxcfg(void)
+{
+ /*
+ * Effects: Uses serial presence detect to set the
+ * ECC support flags in the NBXCFG register
+ * FIXME: Check for illegal/unsupported ram configurations and abort
+ */
+ unsigned device;
+
+ for(device = 0x50; device <= 0x53; device += 1) {
+ int byte;
+
+ byte = 0; /* Disable ECC */
+ /* 0 == None, 1 == Parity, 2 == ECC */
+ if (byte != 2) continue;
+
+ /* set the device I'm talking too */
+ __builtin_outb(device, 0x1004);
+
+ /* poll for transaction completion */
+ byte = __builtin_inb(0x10);
+ while(byte == 0) {
+ byte = __builtin_inb(0x10);
+ }
+ }
+}
diff --git a/util/romcc/tests/simple_test62.c b/util/romcc/tests/simple_test62.c
new file mode 100644
index 0000000000..8fed660c5a
--- /dev/null
+++ b/util/romcc/tests/simple_test62.c
@@ -0,0 +1,7 @@
+static const int foo = 1;
+
+static void main(void)
+{
+ int x;
+ x = foo;
+}
diff --git a/util/romcc/tests/simple_test63.c b/util/romcc/tests/simple_test63.c
new file mode 100644
index 0000000000..b7df0808a7
--- /dev/null
+++ b/util/romcc/tests/simple_test63.c
@@ -0,0 +1,8 @@
+static const int foo[] = { 1, 2 };
+
+static void main(void)
+{
+ int x, y;
+ x = foo[0];
+ y = foo[1];
+}
diff --git a/util/romcc/tests/simple_test64.c b/util/romcc/tests/simple_test64.c
new file mode 100644
index 0000000000..389b1c1e32
--- /dev/null
+++ b/util/romcc/tests/simple_test64.c
@@ -0,0 +1,12 @@
+static void main(void)
+{
+ static const int foo = 2;
+ switch(foo) {
+ case 1:
+ break;
+ case 2:
+ break;
+ default:
+ break;
+ }
+}
diff --git a/util/romcc/tests/simple_test65.c b/util/romcc/tests/simple_test65.c
new file mode 100644
index 0000000000..642882c2a2
--- /dev/null
+++ b/util/romcc/tests/simple_test65.c
@@ -0,0 +1,10 @@
+enum tag {
+ X=1,
+ Y=2,
+};
+static void main(void)
+{
+ enum tag foo;
+ foo = Y;
+
+}
diff --git a/util/romcc/tests/simple_test66.c b/util/romcc/tests/simple_test66.c
new file mode 100644
index 0000000000..5857855700
--- /dev/null
+++ b/util/romcc/tests/simple_test66.c
@@ -0,0 +1,25 @@
+typedef unsigned char uint8_t;
+static unsigned int generate_row(uint8_t row, uint8_t maxnodes)
+{
+
+ unsigned int ret=0x00010101;
+ static const unsigned int rows_2p[2][2] = {
+ { 0x00050101, 0x00010404 },
+ { 0x00010404, 0x00050101 }
+ };
+ if(maxnodes>2) {
+ maxnodes=2;
+ }
+ if (row < maxnodes) {
+ ret=rows_2p[0][row];
+ }
+ return ret;
+}
+
+static void setup_node(void)
+{
+ unsigned char row;
+ for(row=0; row< 2; row++) {
+ __builtin_outl(generate_row(row, 2), 0x1234);
+ }
+}
diff --git a/util/romcc/tests/simple_test67.c b/util/romcc/tests/simple_test67.c
new file mode 100644
index 0000000000..3bfdc5a072
--- /dev/null
+++ b/util/romcc/tests/simple_test67.c
@@ -0,0 +1,24 @@
+static void main(void)
+{
+ unsigned int dch, dcl;
+/* HERE I AM async_lat */
+ unsigned async_lat;
+ int dimms;
+ dimms = 1;
+ async_lat = 0;
+ dch = 0x1234;
+ dcl = __builtin_inl(0x5678);
+ if (!(dcl & (1 << 8))) {
+ if (dimms == 4) {
+ async_lat = 9;
+ }
+ else {
+ async_lat = 8;
+ }
+ }
+ else {
+ async_lat = 6;
+ }
+ dch |= async_lat;
+ __builtin_outl(dch, 0x9abc);
+}
diff --git a/util/romcc/tests/simple_test68.c b/util/romcc/tests/simple_test68.c
new file mode 100644
index 0000000000..dd29658fdc
--- /dev/null
+++ b/util/romcc/tests/simple_test68.c
@@ -0,0 +1,21 @@
+static void main(void)
+{
+ static const int cpu[] = { 0, 1, 2, 3 };
+ int i;
+ for(i = 0; i < sizeof(cpu)/sizeof(cpu[0]); i++) {
+ static const unsigned int register_values[] = {
+ 0x0000c144, 0x0000f8f8, 0x00000000,
+ 0x0000c14C, 0x0000f8f8, 0x00000001,
+ 0x0000c154, 0x0000f8f8, 0x00000002,
+ 0x0000c15C, 0x0000f8f8, 0x00000003,
+ 0x0000c164, 0x0000f8f8, 0x00000004,
+ 0x0000c16C, 0x0000f8f8, 0x00000005,
+ 0x0000c174, 0x0000f8f8, 0x00000006,
+ 0x0000c17C, 0x0000f8f8, 0x00000007,
+ };
+ int j;
+ int max = sizeof(register_values)/sizeof(register_values[0]);
+ for(j = 0; j < max; j += 3) {
+ }
+ }
+}