6 #include <device/pci_def.h>
11 static int is_cpu_pre_c0(void)
16 #define PCI_ADDR(BUS, DEV, FN, WHERE) ( \
17 (((BUS) & 0xFF) << 16) | \
18 (((DEV) & 0x1f) << 11) | \
19 (((FN) & 0x07) << 8) | \
22 #define PCI_DEV(BUS, DEV, FN) ( \
23 (((BUS) & 0xFF) << 16) | \
24 (((DEV) & 0x1f) << 11) | \
27 #define PCI_ID(VENDOR_ID, DEVICE_ID) \
28 ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
30 typedef unsigned device_t;
32 unsigned char pci_register[256*5*3*256];
34 static uint8_t pci_read_config8(device_t dev, unsigned where)
38 return pci_register[addr];
41 static uint16_t pci_read_config16(device_t dev, unsigned where)
45 return pci_register[addr] | (pci_register[addr + 1] << 8);
48 static uint32_t pci_read_config32(device_t dev, unsigned where)
53 value = pci_register[addr] |
54 (pci_register[addr + 1] << 8) |
55 (pci_register[addr + 2] << 16) |
56 (pci_register[addr + 3] << 24);
62 static void pci_write_config8(device_t dev, unsigned where, uint8_t value)
66 pci_register[addr] = value;
69 static void pci_write_config16(device_t dev, unsigned where, uint16_t value)
73 pci_register[addr] = value & 0xff;
74 pci_register[addr + 1] = (value >> 8) & 0xff;
77 static void pci_write_config32(device_t dev, unsigned where, uint32_t value)
81 pci_register[addr] = value & 0xff;
82 pci_register[addr + 1] = (value >> 8) & 0xff;
83 pci_register[addr + 2] = (value >> 16) & 0xff;
84 pci_register[addr + 3] = (value >> 24) & 0xff;
87 #define PCI_DEV_INVALID (0xffffffffU)
88 static device_t pci_locate_device(unsigned pci_id, device_t dev)
90 for(; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0,0,1)) {
92 id = pci_read_config32(dev, 0);
97 return PCI_DEV_INVALID;
103 static void uart_tx_byte(unsigned char data)
105 write(STDOUT_FILENO, &data, 1);
107 static void hlt(void)
111 #include "../../../arch/i386/lib/console.c"
113 unsigned long log2(unsigned long x)
115 // assume 8 bits per byte.
116 unsigned long i = 1 << (sizeof(x)*8 - 1);
117 unsigned long pow = sizeof(x) * 8 - 1;
120 static const char errmsg[] = " called with invalid parameter of 0\n";
121 write(STDERR_FILENO, __func__, sizeof(__func__) - 1);
122 write(STDERR_FILENO, errmsg, sizeof(errmsg) - 1);
125 for(; i > x; i >>= 1, pow--)
131 typedef struct msr_struct
137 static inline msr_t rdmsr(unsigned index)
145 static inline void wrmsr(unsigned index, msr_t msr)
151 #define SIO_BASE 0x2e
153 static void hard_reset(void)
155 /* FIXME implement the hard reset case... */
159 static void memreset_setup(void)
164 static void memreset(int controllers, const struct mem_controller *ctrl)
169 static inline void activate_spd_rom(const struct mem_controller *ctrl)
175 static uint8_t spd_mt4lsdt464a[256] =
177 0x80, 0x08, 0x04, 0x0C, 0x08, 0x01, 0x40, 0x00, 0x01, 0x70,
178 0x54, 0x00, 0x80, 0x10, 0x00, 0x01, 0x8F, 0x04, 0x06, 0x01,
179 0x01, 0x00, 0x0E, 0x75, 0x54, 0x00, 0x00, 0x0F, 0x0E, 0x0F,
181 0x25, 0x08, 0x15, 0x08, 0x15, 0x08, 0x00, 0x12, 0x01, 0x4E,
182 0x9C, 0xE4, 0xB7, 0x46, 0x2C, 0xFF, 0x01, 0x02, 0x03, 0x04,
183 0x05, 0x06, 0x07, 0x08, 0x09, 0x01, 0x02, 0x03, 0x04, 0x05,
184 0x06, 0x07, 0x08, 0x09, 0x00,
187 static uint8_t spd_micron_512MB_DDR333[256] =
189 0x80, 0x08, 0x07, 0x0d, 0x0b, 0x02, 0x48, 0x00, 0x04, 0x60,
190 0x70, 0x02, 0x82, 0x04, 0x04, 0x01, 0x0e, 0x04, 0x0c, 0x01,
191 0x02, 0x26, 0xc0, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48,
192 0x2a, 0x80, 0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00,
193 0x00, 0x3c, 0x48, 0x30, 0x28, 0x50, 0x00, 0x01, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195 0x00, 0x00, 0x10, 0x6f, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff,
196 0xff, 0xff, 0x01, 0x33, 0x36, 0x56, 0x44, 0x44, 0x46, 0x31,
197 0x32, 0x38, 0x37, 0x32, 0x47, 0x2d, 0x33, 0x33, 0x35, 0x43,
198 0x33, 0x03, 0x00, 0x03, 0x23, 0x17, 0x07, 0x5a, 0xb2, 0x00,
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
202 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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
217 static uint8_t spd_micron_256MB_DDR333[256] =
219 0x80, 0x08, 0x07, 0x0d, 0x0b, 0x01, 0x48, 0x00, 0x04, 0x60,
220 0x70, 0x02, 0x82, 0x04, 0x04, 0x01, 0x0e, 0x04, 0x0c, 0x01,
221 0x02, 0x26, 0xc0, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48,
222 0x2a, 0x80, 0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00,
223 0x00, 0x3c, 0x48, 0x30, 0x23, 0x50, 0x00, 0x00, 0x00, 0x00,
224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 0x00, 0x00, 0x00, 0x58, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff,
226 0xff, 0xff, 0x01, 0x31, 0x38, 0x56, 0x44, 0x44, 0x46, 0x36,
227 0x34, 0x37, 0x32, 0x47, 0x2d, 0x33, 0x33, 0x35, 0x43, 0x31,
228 0x20, 0x01, 0x00, 0x03, 0x19, 0x17, 0x05, 0xb2, 0xf4, 0x00,
229 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
232 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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,
248 static uint8_t spd_data[MAX_DIMMS*256];
250 static unsigned spd_count, spd_fail_count;
251 static int spd_read_byte(unsigned device, unsigned address)
255 if ((device < 0x50) || (device >= (0x50 +MAX_DIMMS))) {
264 else if (spd_data[(device << 8) | 2] != 7) {
268 result = spd_data[(device << 8) | address];
271 if (spd_count >= spd_fail_count) {
278 #include "../../../sdram/generic_sdram.c"
282 #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU)
284 static void raminit_main(void)
287 * GPIO28 of 8111 will control H0_MEMRESET_L
288 * GPIO29 of 8111 will control H1_MEMRESET_L
290 static const struct mem_controller cpu[] = {
294 .f0 = PCI_DEV(0, 0x18, 0),
295 .f1 = PCI_DEV(0, 0x18, 1),
296 .f2 = PCI_DEV(0, 0x18, 2),
297 .f3 = PCI_DEV(0, 0x18, 3),
298 .channel0 = { 0x50+0, 0x50+2, 0x50+4, 0x50+6 },
299 .channel1 = { 0x50+1, 0x50+3, 0x50+5, 0x50+7 },
305 .f0 = PCI_DEV(0, 0x19, 0),
306 .f1 = PCI_DEV(0, 0x19, 1),
307 .f2 = PCI_DEV(0, 0x19, 2),
308 .f3 = PCI_DEV(0, 0x19, 3),
309 .channel0 = { 0x50+8, 0x50+10, 0x50+12, 0x50+14 },
310 .channel1 = { 0x50+9, 0x50+11, 0x50+13, 0x50+15 },
316 sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
320 static void reset_tests(void)
322 /* Clear the results of any previous tests */
323 memset(pci_register, 0, sizeof(pci_register));
324 memset(spd_data, 0, sizeof(spd_data));
326 spd_fail_count = UINT_MAX;
328 pci_write_config32(PCI_DEV(0, 0x18, 3), NORTHBRIDGE_CAP,
330 NBCAP_MP| NBCAP_BIG_MP |
331 /* NBCAP_ECC | NBCAP_CHIPKILL_ECC | */
332 (NBCAP_MEMCLK_200MHZ << NBCAP_MEMCLK_SHIFT) |
335 pci_write_config32(PCI_DEV(0, 0x19, 3), NORTHBRIDGE_CAP,
337 NBCAP_MP| NBCAP_BIG_MP |
338 /* NBCAP_ECC | NBCAP_CHIPKILL_ECC | */
339 (NBCAP_MEMCLK_200MHZ << NBCAP_MEMCLK_SHIFT) |
343 static void test1(void)
347 memcpy(&spd_data[0*256], spd_micron_512MB_DDR333, 256);
348 memcpy(&spd_data[1*256], spd_micron_512MB_DDR333, 256);
353 static void do_test2(int i)
356 memcpy(&tmp_buf, &end_buf, sizeof(end_buf));
357 if (setjmp(end_buf) != 0) {
363 print_debug("\r\nSPD will fail after: ");
364 print_debug_hex32(spd_fail_count);
365 print_debug(" accesses.\r\n");
367 memcpy(&spd_data[0*256], spd_micron_512MB_DDR333, 256);
368 memcpy(&spd_data[1*256], spd_micron_512MB_DDR333, 256);
373 memcpy(&end_buf, &tmp_buf, sizeof(end_buf));
376 static void test2(void)
379 for(i = 0; i < 0x48; i++) {
385 int main(int argc, char **argv)
387 if (setjmp(end_buf) != 0) {