| /* |
| * (C) Copyright 2010 Quantenna Communications Inc. |
| * |
| * See file CREDITS for list of people who contributed to this |
| * project. |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License as |
| * published by the Free Software Foundation; either version 2 of |
| * the License, or (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
| * MA 02111-1307 USA |
| */ |
| |
| /***************************************************************************** |
| * This module provides several critical functions for a couple of scenarios: |
| * 1) For the case of uboot in flash, copy code to target |
| * 2) For the case of uboot loaded via serial, make clean copy for subsequent flash ops |
| * 3) Initialize ddr |
| * 4) Clear BSS |
| *****************************************************************************/ |
| |
| #include <config.h> |
| #include <asm/arcregs.h> |
| #include <asm/arch/platform.h> |
| #include <ruby_version.h> |
| #include <topaz_config.h> |
| #include <uboot_header.h> |
| #include "timestamp_autogenerated.h" |
| |
| /*****MACROS**********************************************************************************/ |
| |
| #include "start.inl" |
| |
| /*****TEXT SECTION****************************************************************************/ |
| |
| .section .text |
| .align 4 |
| _start: |
| .globl _start |
| /* |
| * DON'T put any code before .ascii "U-BOOT ...", |
| * bootcfg driver will check "U-BOOT" string. |
| */ |
| #if defined(PIGGY_BUILD) || !defined(RUBY_MINI) |
| b cold_boot |
| #else |
| b run_c |
| #endif |
| /* need easily identifiable tag at beginning of file with version */ |
| .ascii "U-BOOT " RUBY_UBOOT_VERSION "\0" |
| |
| .align 32 |
| early_flash_config_start: |
| .globl early_flash_config_start |
| /* Early board config metadata can go here */ |
| /* Space reserved for first three fields of early_flash_config structure */ |
| #ifdef RUBY_BOOT_METHOD |
| .word RUBY_BOOT_METHOD |
| #else |
| .word RUBY_BOOT_METHOD_TRYLOOP |
| #endif |
| .skip 8 |
| /* This is required for backward compatibility when U-Boot Mini |
| * runs U-Boot code with offset 0x30 */ |
| .align 16 |
| b warm_boot |
| |
| .ascii U_BOOT_TIME_UTC "\0" |
| #ifdef U_BOOT_TINY |
| .ascii U_BOOT_TYPE_TINY |
| #elif defined(U_BOOT_MINI) |
| .ascii U_BOOT_TYPE_MINI |
| #else |
| .ascii U_BOOT_TYPE_LARGE |
| #endif |
| .align 32 |
| |
| early_flash_config_end: |
| .globl early_flash_config_end |
| |
| warm_boot: |
| .globl warm_boot |
| mov r0, warm_boot |
| sub r0, r0, _start |
| b 1f |
| cold_boot: |
| #if defined(PIGGY_BUILD) |
| /* Init CPU timer to get the boot up time */ |
| mov_s r0, 0xFFFFFFFF |
| sr r0, [ARC_REG_TIMER1_LIMIT] |
| mov_s r0, 0 |
| sr r0, [ARC_REG_TIMER1_CNT] |
| mov_s r0, TIMER_CTRL_NH |
| sr r0, [ARC_REG_TIMER1_CTRL] |
| #endif |
| mov_s r0, 0 |
| 1: |
| /* SCRATCH_DATA0 is stored with the offset of warm boot */ |
| sr r0, [SCRATCH_DATA0] |
| |
| #if defined(PIGGY_BUILD) || !defined(RUBY_MINI) |
| ; By default, disable i-cache/d-cache in bootloader start file |
| ; and re-enable in board specific settings in U-boot |
| disable_dcache: |
| lr r0, [0x48] ; dc_ctrl register |
| or r0, r0, 0x1 |
| sr r0, [0x48] |
| |
| #ifdef TOPAZ_ICACHE_WORKAROUND |
| disable_icache: |
| ; Disable i-cache |
| lr r0, [0x11] ; ic_ctrl register |
| or r0, r0, 0x1 |
| sr r0, [0x11] |
| #endif |
| |
| #if defined(PIGGY_BUILD) |
| /* reset bus monitors */ |
| mov r0, 0 |
| mov r1, 0xe0000200 |
| st.di.as r0,[r1, 0x00] |
| st.di.as r0,[r1, 0x10] |
| st.di.as r0,[r1, 0x20] |
| st.di.as r0,[r1, 0x30] |
| st.di.as r0,[r1, 0x40] |
| st.di.as r0,[r1, 0x50] |
| st.di.as r0,[r1, 0x60] |
| st.di.as r0,[r1, 0x70] |
| ld.di.as r0,[r1, 0x00] |
| ld.di.as r0,[r1, 0x10] |
| ld.di.as r0,[r1, 0x20] |
| ld.di.as r0,[r1, 0x30] |
| ld.di.as r0,[r1, 0x40] |
| ld.di.as r0,[r1, 0x50] |
| ld.di.as r0,[r1, 0x60] |
| ld.di.as r0,[r1, 0x70] |
| #endif |
| |
| M_REMOVE_FROM_RESET |
| M_GOTO_IF_EXEC_REMAPPED_SRAM run_c |
| #ifdef FLIPBIT |
| M_IF_BOOT_FROM_FLASH |
| bne ruby_flip_mmap /* if we are running not from flash call the flip routine to |
| * flip the bit in place; will return to ruby_boot label */ |
| #endif |
| j ruby_boot - TEXT_BASE + RUBY_SPI_FLASH_ADDR /* jump to physical spi address */ |
| |
| ruby_boot: |
| .globl ruby_boot |
| M_IF_BOOT_FROM_FLASH |
| bne run_c |
| #ifdef FLIPBIT |
| M_REMAP_MEM |
| #endif |
| M_COPY_UBOOT TEXT_BASE, RUBY_SPI_FLASH_ADDR |
| j run_c |
| #endif /* defined(PIGGY_BUILD) || !defined(RUBY_MINI) */ |
| |
| run_c: |
| M_FILL_BSS |
| #if defined(CONFIG_ARC_MAKE_UBOOT_COPY) && \ |
| (defined(PIGGY_BUILD) || !defined(RUBY_MINI)) |
| M_COPY_UBOOT CONFIG_ARC_FREE_BEGIN, TEXT_BASE |
| #endif |
| M_GOTO_C_CODE |
| |
| /*********************************************************************************************/ |