static void test_memory(u32 memory) { volatile u32 *read; volatile u32 *write; u32 pattern; u8 check; u16 i; do { check = 0; read = write = (volatile u32 *) memory; pattern = 0xAA55AA55; for (i = 0; i < 4; i++) { *write++ = pattern; pattern = ~pattern; } putc_NS16550(debug_uart, 'S'); pattern = 0xAA55AA55; for (i = 0; i < 4; i++) { check += (pattern == *read++) ? 1 : 0; pattern = ~pattern; } } while (check < 4); }
void putstr(NS16550_t debug_uart, const char *s) { while (*s) { putc_NS16550(debug_uart, *s++); } }
int main(void) { int disk; int stage2ImageNumber; int status; /* remove the pending reset again */ writel(0xFFFFFFFF, GPIO_B_CLR_OE); writel((readl(SYS_CTRL_GPIO_TERSEL_CTRL1) & ~0x4), SYS_CTRL_GPIO_TERSEL_CTRL1); writel((readl(SYS_CTRL_GPIO_SECSEL_CTRL1) & ~0x4), SYS_CTRL_GPIO_SECSEL_CTRL1); writel((readl(SYS_CTRL_GPIO_PRIMSEL_CTRL1) & ~0x4), SYS_CTRL_GPIO_PRIMSEL_CTRL1); ddr_control = 0; stage2_size = 120000; stage2ImageNumber = 0; stage2_ram_addr = 0x48d00000; header_length = (u32 *) (stage2_ram_addr - 8); header_crc = (u32 *) (stage2_ram_addr - 4); // Base the UART divider on the system clock int baud_divisor_x16 = NOMINAL_SYSCLK / 115200; if (readl(CONFIG_REGISTER) != readl(START_OF_ROM)) { /* use FPGA system clock speed. */ baud_divisor_x16 = FPGA_CLK / 115200; } else { /* use ASIC nominal system clock. */ baud_divisor_x16 = NOMINAL_SYSCLK / 115200; } start_timer(); set_pll(); // Initialise the UART to be used by the CoPro for debug messages debug_uart = (NS16550_t) UART_2_BASE; init_NS16550(debug_uart, baud_divisor_x16); putc_NS16550(debug_uart, 'N'); init_ddr(); putc_NS16550(debug_uart, 'A'); test_memory(stage2_ram_addr); /* sends 'S' after writing */ putc_NS16550(debug_uart, 'O'); /* no need to re-initialise SATA controller just load details. */ if ((readl(BOOT_STATUS0) == 0x01) || (readl(BOOT_VERSION) == 0x36303030ul)) { disk = 0; } else { disk = 1; } do { init_sata_hw(); status = run_sata(stage2_disk_sector[stage2ImageNumber], stage2_size, (u32 *) header_length, disk); if (status == 0) { putstr(debug_uart, "X"); } else { putstr(debug_uart, "x"); } if (stage2ImageNumber > 0) { putstr(debug_uart, "R"); } else { putstr(debug_uart, "_"); } putc_NS16550(debug_uart, (char) ('0' + (char) disk)); /* try the backup stage2 on this disk first (first tim round, at least we know it is working to some extent, go to next disk if this wraps round */ if (++stage2ImageNumber >= numStage2Images) { stage2ImageNumber = 0; if (++disk > 1) { disk = 0; } } } while (! (status != 0 && *header_length && *header_length <= stage2_size && *header_crc == crc32(0, (unsigned char *) stage2_ram_addr, *header_length))); putstr(debug_uart, "800\r\n"); putstr(debug_uart, build_string); putc_NS16550(debug_uart, '\r'); putc_NS16550(debug_uart, '\n'); #if (OVERCLOCK_PLL) putstr(debug_uart, "Overclocking with "); putstr(debug_uart, ultohex(OVERCLOCK_PLL)); putc_NS16550(debug_uart, ' '); #endif // OVERCLOCK_PLL ((void (*)(void)) stage2_ram_addr) (); return 0; }