Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 1 | #define ASSEMBLY 1 |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 2 | #include <stdint.h> |
| 3 | #include <device/pci_def.h> |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 4 | #include <arch/io.h> |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 5 | #include <device/pnp_def.h> |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 6 | #include <arch/romcc_io.h> |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 7 | #include <arch/smp/lapic.h> |
| 8 | #include "option_table.h" |
| 9 | #include "pc80/mc146818rtc_early.c" |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 10 | #include "pc80/serial.c" |
| 11 | #include "arch/i386/lib/console.c" |
| 12 | #include "ram/ramtest.c" |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 13 | #include "northbridge/amd/amdk8/incoherent_ht.c" |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 14 | #include "southbridge/amd/amd8111/amd8111_early_smbus.c" |
| 15 | #include "northbridge/amd/amdk8/raminit.h" |
| 16 | #include "cpu/k8/apic_timer.c" |
| 17 | #include "lib/delay.c" |
| 18 | #include "cpu/p6/boot_cpu.c" |
| 19 | #include "northbridge/amd/amdk8/reset_test.c" |
Stefan Reinauer | b01fb94 | 2004-03-24 12:28:18 +0000 | [diff] [blame] | 20 | #include "northbridge/amd/amdk8/debug.c" |
Ronald G. Minnich | b56ef07 | 2003-10-15 20:05:11 +0000 | [diff] [blame] | 21 | #include "northbridge/amd/amdk8/cpu_rev.c" |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 22 | #include "superio/winbond/w83627hf/w83627hf_early_serial.c" |
Ronald G. Minnich | b56ef07 | 2003-10-15 20:05:11 +0000 | [diff] [blame] | 23 | |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 24 | #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) |
| 25 | |
| 26 | static void hard_reset(void) |
| 27 | { |
| 28 | set_bios_reset(); |
| 29 | |
| 30 | /* enable cf9 */ |
Stefan Reinauer | 01f887d | 2004-03-25 09:31:10 +0000 | [diff] [blame] | 31 | pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 32 | /* reset */ |
| 33 | outb(0x0e, 0x0cf9); |
| 34 | } |
| 35 | |
| 36 | static void soft_reset(void) |
| 37 | { |
| 38 | set_bios_reset(); |
Stefan Reinauer | 01f887d | 2004-03-25 09:31:10 +0000 | [diff] [blame] | 39 | pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 40 | } |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 41 | |
| 42 | static void memreset_setup(void) |
| 43 | { |
Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 44 | if (is_cpu_pre_c0()) { |
| 45 | outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 17); |
| 46 | outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 16); //REVC_MEMRST_EN=0 |
| 47 | } else { |
| 48 | outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 16); //REVC_MEMRST_EN=1 |
| 49 | } |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 50 | } |
| 51 | |
| 52 | static void memreset(int controllers, const struct mem_controller *ctrl) |
| 53 | { |
Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 54 | if (is_cpu_pre_c0()) { |
| 55 | udelay(800); |
| 56 | outb((0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 17); //REVB_MEMRST_L=1 |
| 57 | udelay(90); |
| 58 | } |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 59 | } |
| 60 | |
| 61 | static unsigned int generate_row(uint8_t node, uint8_t row, uint8_t maxnodes) |
| 62 | { |
| 63 | /* Routing Table Node i |
| 64 | * |
| 65 | * F0: 0x40, 0x44, 0x48, 0x4c, 0x50, 0x54, 0x58, 0x5c |
| 66 | * i: 0, 1, 2, 3, 4, 5, 6, 7 |
| 67 | * |
| 68 | * [ 0: 3] Request Route |
| 69 | * [0] Route to this node |
| 70 | * [1] Route to Link 0 |
| 71 | * [2] Route to Link 1 |
| 72 | * [3] Route to Link 2 |
| 73 | * [11: 8] Response Route |
| 74 | * [0] Route to this node |
| 75 | * [1] Route to Link 0 |
| 76 | * [2] Route to Link 1 |
| 77 | * [3] Route to Link 2 |
| 78 | * [19:16] Broadcast route |
| 79 | * [0] Route to this node |
| 80 | * [1] Route to Link 0 |
| 81 | * [2] Route to Link 1 |
| 82 | * [3] Route to Link 2 |
| 83 | */ |
| 84 | |
Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 85 | uint32_t ret = 0x00010101; /* default row entry */ |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 86 | |
| 87 | static const unsigned int rows_2p[2][2] = { |
| 88 | { 0x00050101, 0x00010404 }, |
| 89 | { 0x00010404, 0x00050101 } |
| 90 | }; |
| 91 | |
Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 92 | if (maxnodes > 2) { |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 93 | print_debug("this mainboard is only designed for 2 cpus\r\n"); |
Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 94 | maxnodes = 2; |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 95 | } |
| 96 | |
Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 97 | if (!(node >= maxnodes || row >= maxnodes)) { |
| 98 | ret = rows_2p[node][row]; |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 99 | } |
| 100 | |
| 101 | return ret; |
| 102 | } |
| 103 | |
Stefan Reinauer | 163309a | 2003-11-04 12:06:03 +0000 | [diff] [blame] | 104 | static inline void activate_spd_rom(const struct mem_controller *ctrl) |
| 105 | { |
| 106 | /* nothing to do */ |
| 107 | } |
| 108 | |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 109 | static inline int spd_read_byte(unsigned device, unsigned address) |
| 110 | { |
| 111 | return smbus_read_byte(device, address); |
| 112 | } |
| 113 | |
Stefan Reinauer | f5f10d1 | 2003-08-28 13:43:03 +0000 | [diff] [blame] | 114 | #include "northbridge/amd/amdk8/raminit.c" |
Stefan Reinauer | f4440e6 | 2003-08-28 15:08:43 +0000 | [diff] [blame] | 115 | #include "northbridge/amd/amdk8/coherent_ht.c" |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 116 | #include "sdram/generic_sdram.c" |
| 117 | |
Stefan Reinauer | f5f10d1 | 2003-08-28 13:43:03 +0000 | [diff] [blame] | 118 | #include "resourcemap.c" /* tyan does not want the default */ |
| 119 | |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 120 | #define FIRST_CPU 1 |
| 121 | #define SECOND_CPU 1 |
| 122 | #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU) |
| 123 | static void main(void) |
| 124 | { |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 125 | static const struct mem_controller cpu[] = { |
| 126 | #if FIRST_CPU |
| 127 | { |
| 128 | .node_id = 0, |
| 129 | .f0 = PCI_DEV(0, 0x18, 0), |
| 130 | .f1 = PCI_DEV(0, 0x18, 1), |
| 131 | .f2 = PCI_DEV(0, 0x18, 2), |
| 132 | .f3 = PCI_DEV(0, 0x18, 3), |
| 133 | .channel0 = { (0xa<<3)|0, (0xa<<3)|2, 0, 0 }, |
| 134 | .channel1 = { (0xa<<3)|1, (0xa<<3)|3, 0, 0 }, |
| 135 | }, |
| 136 | #endif |
| 137 | #if SECOND_CPU |
| 138 | { |
| 139 | .node_id = 1, |
| 140 | .f0 = PCI_DEV(0, 0x19, 0), |
| 141 | .f1 = PCI_DEV(0, 0x19, 1), |
| 142 | .f2 = PCI_DEV(0, 0x19, 2), |
| 143 | .f3 = PCI_DEV(0, 0x19, 3), |
| 144 | .channel0 = { (0xa<<3)|4, (0xa<<3)|6, 0, 0 }, |
| 145 | .channel1 = { (0xa<<3)|5, (0xa<<3)|7, 0, 0 }, |
| 146 | }, |
| 147 | #endif |
| 148 | }; |
Li-Ta Lo | edeff59 | 2004-03-25 17:50:06 +0000 | [diff] [blame] | 149 | |
| 150 | static const struct ht_chain ht_c[] = { |
| 151 | { |
| 152 | .udev = PCI_DEV(0, 0x18, 0), |
| 153 | .upos = 0xc0, |
Li-Ta Lo | 4cd79f3 | 2004-03-26 21:34:04 +0000 | [diff] [blame] | 154 | .devreg = 0xe0, |
| 155 | }, |
Li-Ta Lo | edeff59 | 2004-03-25 17:50:06 +0000 | [diff] [blame] | 156 | { |
| 157 | .udev = PCI_DEV(0, 0x18, 0), |
| 158 | .upos = 0x80, |
Li-Ta Lo | 4cd79f3 | 2004-03-26 21:34:04 +0000 | [diff] [blame] | 159 | .devreg = 0xe4, |
| 160 | }, |
Li-Ta Lo | edeff59 | 2004-03-25 17:50:06 +0000 | [diff] [blame] | 161 | }; |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 162 | int needs_reset; |
Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 163 | |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 164 | enable_lapic(); |
| 165 | init_timer(); |
Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 166 | |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 167 | if (cpu_init_detected()) { |
| 168 | asm("jmp __cpu_reset"); |
| 169 | } |
Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 170 | |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 171 | distinguish_cpu_resets(); |
| 172 | if (!boot_cpu()) { |
| 173 | stop_this_cpu(); |
| 174 | } |
Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 175 | |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 176 | w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE); |
| 177 | uart_init(); |
| 178 | console_init(); |
Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 179 | |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 180 | setup_s2885_resource_map(); |
| 181 | needs_reset = setup_coherent_ht_domain(); |
Li-Ta Lo | edeff59 | 2004-03-25 17:50:06 +0000 | [diff] [blame] | 182 | // needs_reset |= ht_setup_chain(PCI_DEV(0, 0x18, 0), 0xc0); |
| 183 | needs_reset |= ht_setup_chains(ht_c, sizeof(ht_c)/sizeof(ht_c[0])); |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 184 | if (needs_reset) { |
Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 185 | print_info("ht reset -\r\n"); |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 186 | soft_reset(); |
| 187 | } |
Li-Ta Lo | edeff59 | 2004-03-25 17:50:06 +0000 | [diff] [blame] | 188 | #if 0 |
| 189 | dump_pci_devices(); |
| 190 | #endif |
| 191 | |
Ronald G. Minnich | e4fc0ab | 2004-03-12 15:13:38 +0000 | [diff] [blame] | 192 | |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 193 | #if 0 |
| 194 | print_pci_devices(); |
| 195 | #endif |
Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 196 | |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 197 | enable_smbus(); |
Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 198 | |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 199 | #if 0 |
| 200 | dump_spd_registers(&cpu[0]); |
| 201 | #endif |
Li-Ta Lo | 68a5e08 | 2004-03-25 18:04:18 +0000 | [diff] [blame] | 202 | |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 203 | memreset_setup(); |
| 204 | sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); |
| 205 | |
Li-Ta Lo | 5c34bfd | 2004-03-25 18:17:36 +0000 | [diff] [blame] | 206 | #if 0 |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 207 | dump_pci_devices(); |
Li-Ta Lo | 5c34bfd | 2004-03-25 18:17:36 +0000 | [diff] [blame] | 208 | dump_pci_device(PCI_DEV(0, 0x18, 1)); |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 209 | #endif |
| 210 | |
| 211 | /* Check all of memory */ |
| 212 | #if 0 |
| 213 | msr_t msr; |
| 214 | msr = rdmsr(TOP_MEM2); |
| 215 | print_debug("TOP_MEM2: "); |
| 216 | print_debug_hex32(msr.hi); |
| 217 | print_debug_hex32(msr.lo); |
| 218 | print_debug("\r\n"); |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 219 | ram_check(0x00000000, msr.lo+(msr.hi<<32)); |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 220 | #if TOTAL_CPUS < 2 |
| 221 | // Check 16MB of memory @ 0 |
| 222 | ram_check(0x00000000, 0x00100000); |
| 223 | #else |
| 224 | // Check 16MB of memory @ 2GB |
| 225 | ram_check(0x80000000, 0x80100000); |
| 226 | #endif |
| 227 | #endif |
Ronald G. Minnich | fa2df75 | 2003-08-27 14:33:13 +0000 | [diff] [blame] | 228 | } |