📄 test-stage0.c
字号:
/***************************************** Copyright (c) 2002-2004 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the EM86XX boot loader */#include "config.h"#include "uart.h"#include "util.h"#include "io.h"#include "em86xxapi.h"// #define MEMORY_TEST#define YANN_MEMORY_TEST// Enable this for special interactive mode// #define CONFIG_SPECIAL_MODE#define DEFAULT_FREQ_START 150#define DEFAULT_FREQ_END 180#define DEFAULT_FREQ_ALL_BIT idivide(idivide(EM86XX_EXT_CLOCK,((((pll&0x3f0000)>>16)+2)*2))*((pll&0x3ff)+2),1000000)#define DEFAULT_WRITE_DELAY 8// defined in em8600_mem_test.cextern void em8600_mem_test(int start, int end, int w_delay, int def_freq, int adj_only, int fix_latency);// defined in board/test-stage0.cextern void test_board_stage0(loaderconfig_t *config);#ifdef CONFIG_SPECIAL_MODEstatic int stage0_special_mode(void);#else// function prototypesstatic int test_dram(int index, unsigned int dram_size);static int test_dram_data_bus(unsigned long DRAM_controller_base_address, unsigned long DRAM_controller_regs);static int test_dram_addr_bus(unsigned long DRAM_controller_base_address, unsigned long DRAM_controller_regs, unsigned int dram_size);#ifdef MEMORY_TESTstatic int test_dram_memory(unsigned long DRAM_controller_base_address, unsigned long DRAM_controller_regs, unsigned int dram_size);#endif#endif /* CONFIG_SPECIAL_MODE */typedef unsigned char RMuint8;typedef char RMint8;typedef unsigned short RMuint16;typedef short RMint16;typedef unsigned long RMuint32;typedef long RMint32;typedef unsigned char RMbool;typedef char RMascii;typedef int RMstatus;struct gbus;static inline RMuint8 gbus_read_uint8 (struct gbus *h, RMuint32 byte_address){ return *((volatile RMuint8 *) byte_address);}static inline RMuint16 gbus_read_uint16(struct gbus *h, RMuint32 byte_address){ return *((volatile RMuint16 *) byte_address);}static inline RMuint32 gbus_read_uint32(struct gbus *h, RMuint32 byte_address){ return *((volatile RMuint32 *) byte_address);}static inline void gbus_write_uint8 (struct gbus *h, RMuint32 byte_address, RMuint8 data){ *((volatile RMuint8 *) byte_address) = data;}static inline void gbus_write_uint16(struct gbus *h, RMuint32 byte_address, RMuint16 data){ *((volatile RMuint16 *) byte_address) = data;}static inline void gbus_write_uint32(struct gbus *h, RMuint32 byte_address, RMuint32 data){ *((volatile RMuint32 *) byte_address) = data;}void test_stage0(unsigned int configaddr){#ifdef CONFIG_SPECIAL_MODE stage0_special_mode();#else loaderconfig_t *config; int i; unsigned int dram_size; uart_init(); uart_puts("\n\nProduction Board Test Stage 0\n"); config = (loaderconfig_t *) configaddr; if (config->signature != LOADER_CONFIGSIGN) { uart_puts(" Invalid configuration\n"); return; } for (i = 0; i < 2; ++i) { dram_size = CONFIG_GETDRAMSIZE(config->dram_size, i); uart_printf(" DRAM %d (%dMB) : ", i, dram_size); if (dram_size == 0) uart_puts("None\n"); else { if (test_dram(i, dram_size << 20) == 0) uart_puts("Passed\n"); else uart_puts("Failed\n"); } } test_board_stage0(config); return;#endif}#ifndef CONFIG_SPECIAL_MODEint test_dram(int index, unsigned int dram_size){ static unsigned long s_dram_base[] = { MEMORY_BASE_DRAMCTRL0_NC, MEMORY_BASE_DRAMCTRL1_NC, MEMORY_BASE_DRAMCTRL2_NC, }; static unsigned long s_dram_reg[] = { REG_BASE_DRAMCTRL0, REG_BASE_DRAMCTRL1, REG_BASE_DRAMCTRL2, }; unsigned long dram_base = s_dram_base[index]; unsigned long dram_reg = s_dram_reg[index]; uart_puts("[DATABUS] "); if (test_dram_data_bus(dram_base, dram_reg)) return 1; uart_puts("[ADDRBUS] "); if (test_dram_addr_bus(dram_base, dram_reg, dram_size)) return 1; #ifdef MEMORY_TEST uart_puts("[MEMORY]\n"); if (test_dram_memory(dram_base, dram_reg, dram_size)) return 1;#endif#ifdef YANN_MEMORY_TEST uart_puts("[MEMORY ADVANCED]\n"); { unsigned long pll = __raw_readl(REG_BASE_system_block + SYS_clkgen0_pll); em8600_mem_test(DEFAULT_FREQ_START, DEFAULT_FREQ_END, DEFAULT_WRITE_DELAY, DEFAULT_FREQ_ALL_BIT, 0, 0); }#endif return 0;}#define ZONE_1_DELTA_ADDRESS 0x1000 // We write 00..010..00 at DRAM base address and 11..101..11 at // DRAM base address + ZONE_1_DELTA_ADDRESS (needs > 32 and < 1 MB)int test_dram_data_bus(unsigned long DRAM_controller_base_address, unsigned long DRAM_controller_regs){ unsigned int ui32_loop_counter; unsigned int ui32_mask; unsigned int ui32_mem_value; int error = 0; // Test data bus // First write a different data bit on each line ui32_mask = 1; for (ui32_loop_counter = 0; ui32_loop_counter < 32 ; ui32_loop_counter++) { // Set 1 bit to 1 __raw_writel(ui32_mask, DRAM_controller_base_address + (ui32_loop_counter * 4)); // Flush DRAM controller buffer __raw_writel(0, DRAM_controller_regs + DRAM_dunit_flush_buffer); // Set 1 bit to 0 __raw_writel(~ui32_mask, DRAM_controller_base_address + ZONE_1_DELTA_ADDRESS + (ui32_loop_counter * 4)); // Flush DRAM controller buffer __raw_writel(0, DRAM_controller_regs + DRAM_dunit_flush_buffer); ui32_mask <<= 1; // Test next bit on Data BUS } ui32_mask = 1; for (ui32_loop_counter = 0; ui32_loop_counter < 32 ; ui32_loop_counter++) { // Read bit set to 1 ui32_mem_value = __raw_readl(DRAM_controller_base_address + (ui32_loop_counter * 4)); if ((ui32_mem_value & ui32_mask) != ui32_mask) { // Only test this specific bit... uart_printf("Error Data Bus pin %u, bit set to 1 and read 0\n", ui32_loop_counter); error = 1; } // Read bit set to 0 ui32_mem_value = __raw_readl(DRAM_controller_base_address + ZONE_1_DELTA_ADDRESS + (ui32_loop_counter * 4)); if ((ui32_mem_value & ui32_mask) != 0) { // Only test this specific bit... uart_printf("Error Data Bus pin %u, bit set to 0 and read 1\n", ui32_loop_counter); error = 1; } ui32_mask <<= 1; // Test next bit on Data BUS } return error;}#define ADDR_TEST_START 'A'#define ADDR_TEST_NEXT(x) ((x) + 1)int test_dram_addr_bus(unsigned long DRAM_controller_base_address, unsigned long DRAM_controller_regs, unsigned int dram_size){ unsigned int ui32_loop_counter; unsigned int ui32_addr; unsigned char ui8_data, ui8_read; int error = 0; // writes different data to each address bits for (ui32_addr = 0, ui8_data = ADDR_TEST_START; ui32_addr != dram_size; ui32_addr = (ui32_addr == 0) ? 1 : (ui32_addr << 1), ui8_data = ADDR_TEST_NEXT(ui8_data)) { __raw_writeb(ui8_data, DRAM_controller_base_address + ui32_addr); __raw_writel(0, DRAM_controller_regs + DRAM_dunit_flush_buffer); } // read data and verify for (ui32_addr = 0, ui32_loop_counter = 0, ui8_data = ADDR_TEST_START; ui32_addr != dram_size; ui32_addr = (ui32_addr == 0) ? 1 : (ui32_addr << 1), ++ui32_loop_counter, ui8_data = ADDR_TEST_NEXT(ui8_data)) { ui8_read = __raw_readb(DRAM_controller_base_address + ui32_addr); if (ui8_data != ui8_read) { uart_printf("Error Addr Bus pin %u, expected %u but read %u\n", ui32_loop_counter, ui8_data, ui8_read); error = 1; } } return error;}#define MEMTEST_BLOCK_SIZE 0x1000#define CALC_SEED(addr) ((unsigned char) (((((addr) >> 8) & 0xff) + 3) * 5 + ((((addr) >> 16) & 0xff) + 5) * 7))#define CALC_SEED_EXPAND(seed) ((seed) | (((seed) + 1) << 8) | (((seed) + 2) << 16) | (((seed) + 3) << 24))#define CALC_SEED_NEXT(seed) (++(seed))#define CALC_SEED_NEXT4(seed) ((seed) += 0x01030507)#ifdef MEMORY_TESTint test_dram_memory(unsigned long DRAM_controller_base_address, unsigned long DRAM_controller_regs, unsigned int dram_size){ int i, j; unsigned long addr; unsigned int seed, seedtable[MEMTEST_BLOCK_SIZE >> 2]; int error = 0; uart_puts(" "); for (i = 0, addr = DRAM_controller_base_address; i < dram_size / MEMTEST_BLOCK_SIZE; ++i, addr += MEMTEST_BLOCK_SIZE) { if ((i & 0xff) == 0) uart_putc('.'); seed = CALC_SEED(addr); seed = CALC_SEED_EXPAND(seed); for (j = 0; j < (MEMTEST_BLOCK_SIZE >> 2); ++j, CALC_SEED_NEXT4(seed)) seedtable[j] = seed; memcpy((void *) addr, seedtable, MEMTEST_BLOCK_SIZE); } uart_puts("\n "); __raw_writel(0, DRAM_controller_regs + DRAM_dunit_flush_buffer); for (i = 0, addr = DRAM_controller_base_address; i < dram_size / MEMTEST_BLOCK_SIZE; ++i, addr += MEMTEST_BLOCK_SIZE) { if ((i & 0xff) == 0) uart_putc('o'); seed = CALC_SEED(addr); seed = CALC_SEED_EXPAND(seed); for (j = 0; j < (MEMTEST_BLOCK_SIZE >> 2); ++j, CALC_SEED_NEXT4(seed)) seedtable[j] = seed; if (memcmp((void *) addr, seedtable, MEMTEST_BLOCK_SIZE) != 0) { uart_printf("DRAM Error at address 0x%08lx\n", addr); error = 1; } } uart_puts("\n "); return error;}#endif#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -