6 #include <device/pci_def.h>
12 static int is_cpu_pre_c0(void)
17 #define PCI_ADDR(BUS, DEV, FN, WHERE) ( \
18 (((BUS) & 0xFF) << 16) | \
19 (((DEV) & 0x1f) << 11) | \
20 (((FN) & 0x07) << 8) | \
23 #define PCI_DEV(BUS, DEV, FN) ( \
24 (((BUS) & 0xFF) << 16) | \
25 (((DEV) & 0x1f) << 11) | \
28 #define PCI_ID(VENDOR_ID, DEVICE_ID) \
29 ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
31 typedef unsigned device_t;
33 unsigned char pci_register[256*5*3*256];
35 static uint8_t pci_read_config8(device_t dev, unsigned where)
39 return pci_register[addr];
42 static uint16_t pci_read_config16(device_t dev, unsigned where)
46 return pci_register[addr] | (pci_register[addr + 1] << 8);
49 static uint32_t pci_read_config32(device_t dev, unsigned where)
54 value = pci_register[addr] |
55 (pci_register[addr + 1] << 8) |
56 (pci_register[addr + 2] << 16) |
57 (pci_register[addr + 3] << 24);
63 static void pci_write_config8(device_t dev, unsigned where, uint8_t value)
67 pci_register[addr] = value;
70 static void pci_write_config16(device_t dev, unsigned where, uint16_t value)
74 pci_register[addr] = value & 0xff;
75 pci_register[addr + 1] = (value >> 8) & 0xff;
78 static void pci_write_config32(device_t dev, unsigned where, uint32_t value)
82 pci_register[addr] = value & 0xff;
83 pci_register[addr + 1] = (value >> 8) & 0xff;
84 pci_register[addr + 2] = (value >> 16) & 0xff;
85 pci_register[addr + 3] = (value >> 24) & 0xff;
88 #define PCI_DEV_INVALID (0xffffffffU)
89 static device_t pci_locate_device(unsigned pci_id, device_t dev)
91 for(; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0,0,1)) {
93 id = pci_read_config32(dev, 0);
98 return PCI_DEV_INVALID;
104 static void uart_tx_byte(unsigned char data)
106 write(STDOUT_FILENO, &data, 1);
108 static void hlt(void)
112 #include "../../../arch/i386/lib/console.c"
114 unsigned long log2(unsigned long x)
116 // assume 8 bits per byte.
117 unsigned long i = 1 << (sizeof(x)*8 - 1);
118 unsigned long pow = sizeof(x) * 8 - 1;
121 static const char errmsg[] = " called with invalid parameter of 0\n";
122 write(STDERR_FILENO, __func__, sizeof(__func__) - 1);
123 write(STDERR_FILENO, errmsg, sizeof(errmsg) - 1);
126 for(; i > x; i >>= 1, pow--)
132 typedef struct msr_struct
138 static inline msr_t rdmsr(unsigned index)
146 static inline void wrmsr(unsigned index, msr_t msr)
152 #define SIO_BASE 0x2e
154 static void hard_reset(void)
156 /* FIXME implement the hard reset case... */
160 static void memreset_setup(void)
165 static void memreset(int controllers, const struct mem_controller *ctrl)
170 static inline void activate_spd_rom(const struct mem_controller *ctrl)
176 static uint8_t spd_mt4lsdt464a[256] =
178 0x80, 0x08, 0x04, 0x0C, 0x08, 0x01, 0x40, 0x00, 0x01, 0x70,
179 0x54, 0x00, 0x80, 0x10, 0x00, 0x01, 0x8F, 0x04, 0x06, 0x01,
180 0x01, 0x00, 0x0E, 0x75, 0x54, 0x00, 0x00, 0x0F, 0x0E, 0x0F,
182 0x25, 0x08, 0x15, 0x08, 0x15, 0x08, 0x00, 0x12, 0x01, 0x4E,
183 0x9C, 0xE4, 0xB7, 0x46, 0x2C, 0xFF, 0x01, 0x02, 0x03, 0x04,
184 0x05, 0x06, 0x07, 0x08, 0x09, 0x01, 0x02, 0x03, 0x04, 0x05,
185 0x06, 0x07, 0x08, 0x09, 0x00,
188 static uint8_t spd_micron_512MB_DDR333[256] =
190 0x80, 0x08, 0x07, 0x0d, 0x0b, 0x02, 0x48, 0x00, 0x04, 0x60,
191 0x70, 0x02, 0x82, 0x04, 0x04, 0x01, 0x0e, 0x04, 0x0c, 0x01,
192 0x02, 0x26, 0xc0, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48,
193 0x2a, 0x80, 0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x3c, 0x48, 0x30, 0x28, 0x50, 0x00, 0x01, 0x00, 0x00,
195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196 0x00, 0x00, 0x10, 0x6f, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff,
197 0xff, 0xff, 0x01, 0x33, 0x36, 0x56, 0x44, 0x44, 0x46, 0x31,
198 0x32, 0x38, 0x37, 0x32, 0x47, 0x2d, 0x33, 0x33, 0x35, 0x43,
199 0x33, 0x03, 0x00, 0x03, 0x23, 0x17, 0x07, 0x5a, 0xb2, 0x00,
200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
203 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
204 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
205 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
206 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
207 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
208 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
209 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
210 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
211 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
212 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
213 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
214 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
215 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
218 static uint8_t spd_micron_256MB_DDR333[256] =
220 0x80, 0x08, 0x07, 0x0d, 0x0b, 0x01, 0x48, 0x00, 0x04, 0x60,
221 0x70, 0x02, 0x82, 0x04, 0x04, 0x01, 0x0e, 0x04, 0x0c, 0x01,
222 0x02, 0x26, 0xc0, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48,
223 0x2a, 0x80, 0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00,
224 0x00, 0x3c, 0x48, 0x30, 0x23, 0x50, 0x00, 0x00, 0x00, 0x00,
225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226 0x00, 0x00, 0x00, 0x58, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff,
227 0xff, 0xff, 0x01, 0x31, 0x38, 0x56, 0x44, 0x44, 0x46, 0x36,
228 0x34, 0x37, 0x32, 0x47, 0x2d, 0x33, 0x33, 0x35, 0x43, 0x31,
229 0x20, 0x01, 0x00, 0x03, 0x19, 0x17, 0x05, 0xb2, 0xf4, 0x00,
230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
233 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
234 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
235 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
236 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
237 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
238 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
239 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
240 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
241 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
242 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
243 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
244 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
245 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
249 static uint8_t spd_data[MAX_DIMMS*256];
251 static unsigned spd_count, spd_fail_count;
252 static int spd_read_byte(unsigned device, unsigned address)
256 if ((device < 0x50) || (device >= (0x50 +MAX_DIMMS))) {
265 else if (spd_data[(device << 8) | 2] != 7) {
269 result = spd_data[(device << 8) | address];
272 if (spd_count >= spd_fail_count) {
279 #include "../../../sdram/generic_sdram.c"
283 #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU)
285 static void raminit_main(void)
288 * GPIO28 of 8111 will control H0_MEMRESET_L
289 * GPIO29 of 8111 will control H1_MEMRESET_L
291 static const struct mem_controller cpu[] = {
295 .f0 = PCI_DEV(0, 0x18, 0),
296 .f1 = PCI_DEV(0, 0x18, 1),
297 .f2 = PCI_DEV(0, 0x18, 2),
298 .f3 = PCI_DEV(0, 0x18, 3),
299 .channel0 = { 0x50+0, 0x50+2, 0x50+4, 0x50+6 },
300 .channel1 = { 0x50+1, 0x50+3, 0x50+5, 0x50+7 },
306 .f0 = PCI_DEV(0, 0x19, 0),
307 .f1 = PCI_DEV(0, 0x19, 1),
308 .f2 = PCI_DEV(0, 0x19, 2),
309 .f3 = PCI_DEV(0, 0x19, 3),
310 .channel0 = { 0x50+8, 0x50+10, 0x50+12, 0x50+14 },
311 .channel1 = { 0x50+9, 0x50+11, 0x50+13, 0x50+15 },
317 sdram_initialize(ARRAY_SIZE(cpu), cpu);
321 static void reset_tests(void)
323 /* Clear the results of any previous tests */
324 memset(pci_register, 0, sizeof(pci_register));
325 memset(spd_data, 0, sizeof(spd_data));
327 spd_fail_count = UINT_MAX;
329 pci_write_config32(PCI_DEV(0, 0x18, 3), NORTHBRIDGE_CAP,
331 NBCAP_MP| NBCAP_BIG_MP |
332 /* NBCAP_ECC | NBCAP_CHIPKILL_ECC | */
333 (NBCAP_MEMCLK_200MHZ << NBCAP_MEMCLK_SHIFT) |
336 pci_write_config32(PCI_DEV(0, 0x19, 3), NORTHBRIDGE_CAP,
338 NBCAP_MP| NBCAP_BIG_MP |
339 /* NBCAP_ECC | NBCAP_CHIPKILL_ECC | */
340 (NBCAP_MEMCLK_200MHZ << NBCAP_MEMCLK_SHIFT) |
344 static void test1(void)
348 memcpy(&spd_data[0*256], spd_micron_512MB_DDR333, 256);
349 memcpy(&spd_data[1*256], spd_micron_512MB_DDR333, 256);
354 static void do_test2(int i)
357 memcpy(&tmp_buf, &end_buf, sizeof(end_buf));
358 if (setjmp(end_buf) != 0) {
364 print_debug("\r\nSPD will fail after: ");
365 print_debug_hex32(spd_fail_count);
366 print_debug(" accesses.\r\n");
368 memcpy(&spd_data[0*256], spd_micron_512MB_DDR333, 256);
369 memcpy(&spd_data[1*256], spd_micron_512MB_DDR333, 256);
374 memcpy(&end_buf, &tmp_buf, sizeof(end_buf));
377 static void test2(void)
380 for(i = 0; i < 0x48; i++) {
386 int main(int argc, char **argv)
388 if (setjmp(end_buf) != 0) {