/******************************************************************************************** * File: bootstrap.c * Version: 1.0.0 * Copyright: 2013 (c) Guo Wenxue * Description: This C code is the first stage bootloader(named bootstrap) * main code, test on OK6410 board. * ChangeLog: 1, Release initial version on "Mon Feb 25 23:02:41 CST 2013" * *******************************************************************************************/ #include "s3c6410.h" #include "common.h" inline void delay(unsigned long loops) { __asm__ volatile ("1:\n" "subs %0, %1, #1\n" "bne 1b":"=r" (loops):"0"(loops)); } /* OK6410 LED1~LED4 use GPIO: GPM0~GPM3 */ static void led_init(void) { unsigned int regv; /* Set GPM0~GPM3 as GPIO output mode*/ regv = s3c_readl(GPMCON); regv = (regv & ~0xffffU) | 0x1111U; s3c_writel(regv, GPMCON); /* Disable GPM0~GPM3 pull-up/down */ regv = s3c_readl(GPMPUD); regv = (regv & ~0xffU) | 0x00U; s3c_writel(regv, GPMPUD); /* Set GPM0~GPM3 as high level to turn LED1~LED3 off */ regv = s3c_readl(GPMDAT); regv = (regv & ~0xffU) | 0xfU; s3c_writel(regv, GPMDAT); } static void led_display(unsigned int data) { unsigned int regv; regv = s3c_readl(GPMDAT); regv = (regv & 0xf) & ((~data) & 0xf); s3c_writel(regv, GPMDAT); } static int ddr_test(void) { int i; unsigned int val; for (i=0; i<0x1000; i++) { s3c_writel(0x55aaaa55, (MEMORY_BASE_ADDRESS + i*0x100)); val = s3c_readl(MEMORY_BASE_ADDRESS + i*0x100); if (val != 0x55aaaa55) return -1; s3c_writel(0xaa5555aa, (MEMORY_BASE_ADDRESS + i*0x100)); val = s3c_readl(MEMORY_BASE_ADDRESS + i*0x100); if (val != 0xaa5555aa) return -1; } return i; } int main() { int rv = 0; char *addr = (char *)MEMORY_BASE_ADDRESS; led_init(); led_display(0x0f); serial_init(CONFIG_BAUDRATE); serial_puts("Bootstrap already running...\n"); rv = ddr_test(); if (rv < 0) { serial_puts("ddr test faild.\n"); } else serial_puts("1. ddr init/test successful.\n"); serial_puts("Xmodem Receive now!\n"); xmodem_recv(addr); return 0; }