📄 head-arm-netarm.s
字号:
/* * =================== STARTUP CODE, Kernel 2.4.x ===================== * * linux/arch/armnommu/kernel/head-arm-netarm.S * * Copyright (C) 2000, 2001 NETsilicon, Inc. * Copyright (C) 2000, 2001 Red Hat, Inc. * * This software is copyrighted by Red Hat. LICENSEE agrees that * it will not delete this copyright notice, trademarks or protective * notices from any copy made by LICENSEE. * * This software is provided "AS-IS" and any express or implied * warranties or conditions, including but not limited to any * implied warranties of merchantability and fitness for a particular * purpose regarding this software. In no event shall Red Hat * be liable for any indirect, consequential, or incidental damages, * loss of profits or revenue, loss of use or data, or interruption * of business, whether the alleged damages are labeled in contract, * tort, or indemnity. * * 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. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * * author(s) : Joe deBlaquiere */#include <linux/config.h>#include <linux/linkage.h>#include <asm/mach-types.h>#include <asm/arch/netarm_registers.h>#include <asm/arch/netarm_mmap.h>#define NETARM_INIT_CPSR (CPSR_I_BIT | CPSR_F_BIT | CPSR_SVC_MODE)/* * Define which output pin to use for NET+ARM development board blink routine */#define NA_YELLOW_LED 0x04#define NA_GREEN_LED 0x02#ifdef CONFIG_NETARM_EMLIN/* The (one) green LED is on bit 6 (0x40) */#define NA_BLINK_LED 0x40#define NA_FAIL_LED 0x40#else/* Use green and yellow LEDs */#define NA_BLINK_LED NA_YELLOW_LED#define NA_FAIL_LED NA_GREEN_LED#endif/* * We place the page tables 16K below TEXTADDR. Therefore, we must make sure * that TEXTADDR is correctly set. Currently, we expect the least significant * "short" to be 0x8000, but we could probably relax this restriction to * TEXTADDR > PAGE_OFFSET + 0x4000 * * Note that swapper_pg_dir is the virtual address of the page tables, and * pgtbl gives us a position-independent reference to these tables. We can * do this because stext == TEXTADDR * * swapper_pg_dir, pgtbl and krnladr are all closely related. * (FIXME: do we need this at all in a no-mmu configuration? rp) */ .globl SYMBOL_NAME(swapper_pg_dir) .equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x4000 /* * This define is used to determine the number of wait states needed * for the 90 ns flash used on the NET+ARM reference board. The macro * is only valid for 90 ns flash. To get this value, the following * calculation was used: * * ceil(90 / ((1 / FSYSCLK) * 1000)) - 1 * * This define gives the same value as the above calculation, but based * on the PLLCNT (instead of on the FSYSCLK).*/#define FLASH_90ns_WAIT_STATES ((NETARM_PLL_COUNT_VAL + 2) / 3) .text .align 12/* * Reset condition : * R14_svc = unknown * SPSR_svc = CPSR * CPSR = 0b1101_0011 ; not IRQ, no FIQ, SVC mode * PC = 0x0 */ .section ".text.init",#alloc,#execinstr .type stext, #functionENTRY(stext) mov r0, #NETARM_INIT_CPSR msr cpsr, r0/* delay (0x10000) to allow developer to attach debugger before boot */ mov r1, #0x100001: subs r1, r1, #1 bge 1b /* * prior to software reset : need to set pin PORTC4 to be *HRESET */ ldr r4, =NETARM_GEN_MODULE_BASE ldr r1, =( NETARM_GEN_PORT_MODE(0x10) | \ NETARM_GEN_PORT_DIR(0x10) ) str r1, [r4, #+NETARM_GEN_PORTC] /* * software reset : see HW Ref. Guide 8.2.4 : Software Service Register * for an explanation of this process */ ldr r4, =NETARM_GEN_MODULE_BASE ldr r1, =NETARM_GEN_SW_SVC_RESETA str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE] ldr r1, =NETARM_GEN_SW_SVC_RESETB str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE] ldr r1, =NETARM_GEN_SW_SVC_RESETA str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE] ldr r1, =NETARM_GEN_SW_SVC_RESETB str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]/* * set up PLL and System Config */@ r4 already set ldr r4, =NETARM_GEN_MODULE_BASE#ifdef CONFIG_NETARM_NET40_REV2 ldr r1, =( NETARM_GEN_SYS_CFG_LENDIAN | \ NETARM_GEN_SYS_CFG_BUSFULL | \ NETARM_GEN_SYS_CFG_USER_EN | \ NETARM_GEN_SYS_CFG_ALIGN_ABORT | \ NETARM_GEN_SYS_CFG_BUSARB_INT )#else ldr r1, =( NETARM_GEN_SYS_CFG_LENDIAN | \ NETARM_GEN_SYS_CFG_BUSFULL | \ NETARM_GEN_SYS_CFG_USER_EN | \ NETARM_GEN_SYS_CFG_ALIGN_ABORT | \ NETARM_GEN_SYS_CFG_BUSARB_INT | \ NETARM_GEN_SYS_CFG_BUSMON_EN )#endif str r1, [r4, #+NETARM_GEN_SYSTEM_CONTROL] ldr r1, =NETARM_GEN_PLL_CTL_PLLCNT(NETARM_PLL_COUNT_VAL) str r1, [r4, #+NETARM_GEN_PLL_CONTROL ]/* * initialize both serial ports */ bl _netarm_debug_serial_init mov r0, #'A' bl _printch /* * if CS0 is already mapped high, assume it's mapped correctly */ ldr r4, =NETARM_MEM_MODULE_BASE ldr r1, [r4, #NETARM_MEM_CS0_BASE_ADDR] ldr r2, =NETARM_MEM_BAR_BASE_MASK and r1, r1, r2 cmp r1, #0 bne _exec_in_RAM mov r0, #'B' bl _printch/* b _netarm_led_FAIL2 *//* * since the system boots without knowing the size of the ROM * the code is mirrored on every page... so we'll jump to * a page way up where we're moving the PROM to */ ldr pc, =(_jump_to_high + NETARM_MMAP_CS0_BASE)/* * either we now set up the RAM or we were always running from RAM * and we didn't change the memory settings... */_jump_to_high: mov r0, #'C' bl _printch /* * test point - jump to blink */ ldr r4, =NETARM_MEM_MODULE_BASE#ifndef CONFIG_NETARM_EMLIN/* Settings for NetSilicon's development boards (NET+40, NET+50, ...) *//* mem config */ ldr r1, =( NETARM_MEM_REFR_PERIOD_USEC(16) | \ NETARM_MEM_CFG_REFRESH_EN | \ NETARM_MEM_CFG_REFR_CYCLE_5CLKS ) str r1, [r4, #NETARM_MEM_MODULE_CONFIG] @ mov r0, #'D'@ bl _printch /* CS0 */ ldr r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS0_BASE) | \ NETARM_MEM_BAR_DRAM_FP | \ NETARM_MEM_BAR_DRAM_MUX_INT | \ NETARM_MEM_BAR_DRAM_MUX_BAL | \ NETARM_MEM_BAR_VALID ) str r1, [r4, #NETARM_MEM_CS0_BASE_ADDR]@ mov r0, #'E'@ bl _printch /* trust that the bus size for flash was strapped correctly */ /* this saves the bus width in r2 and then ORs it back in */ /* it's a pretty safe assumption, otherwise it wouldn't boot */ ldr r2, [r4, #NETARM_MEM_CS0_OPTIONS] and r2, r2, #NETARM_MEM_OPT_BUS_SIZE_MASK/* just a test: assume 32 bit flash mem --rp *//* mov r2, #NETARM_MEM_OPT_32BIT */ ldr r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS0_MASK) | \ NETARM_MEM_OPT_WAIT_STATES(FLASH_90ns_WAIT_STATES) | \ NETARM_MEM_OPT_BCYC_2 | \ NETARM_MEM_OPT_BSIZE_4 | \ NETARM_MEM_OPT_READ_ASYNC | \ NETARM_MEM_OPT_WRITE_ASYNC ) orr r1, r1, r2 str r1, [r4, #NETARM_MEM_CS0_OPTIONS]@ mov r0, #'F'@ bl _printch#ifdef CONFIG_NETARM_NET40_REV2/* CS1 */ ldr r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS1_MASK) | \ NETARM_MEM_OPT_BCYC_2 | \ NETARM_MEM_OPT_BSIZE_16 | \ NETARM_MEM_OPT_WAIT_STATES(0) | \ NETARM_MEM_OPT_32BIT | \ NETARM_MEM_OPT_READ_ASYNC | \ NETARM_MEM_OPT_WRITE_ASYNC ) str r1, [r4, #NETARM_MEM_CS1_OPTIONS]@ mov r0, #'G'@ bl _printch ldr r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS1_BASE) | \ NETARM_MEM_BAR_DRAM_SYNC | \ NETARM_MEM_BAR_DRAM_MUX_INT | \ NETARM_MEM_BAR_DRAM_MUX_UNBAL | \ NETARM_MEM_BAR_DRAM_SEL | \ NETARM_MEM_BAR_BURST_EN | \ NETARM_MEM_BAR_VALID ) str r1, [r4, #NETARM_MEM_CS1_BASE_ADDR]@ mov r0, #'H'@ bl _printch/* CS2 */ ldr r1, =( 0 ) str r1, [r4, #NETARM_MEM_CS2_BASE_ADDR]@ mov r0, #'I'@ bl _printch ldr r1, =( 0 ) str r1, [r4, #NETARM_MEM_CS2_OPTIONS]@ mov r0, #'J'@ bl _printch#else/* CS1 */ ldr r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS1_MASK) | \ NETARM_MEM_OPT_BCYC_3 | \ NETARM_MEM_OPT_BSIZE_4 | \ NETARM_MEM_OPT_WAIT_STATES(0) | \ NETARM_MEM_OPT_32BIT | \ NETARM_MEM_OPT_READ_ASYNC | \ NETARM_MEM_OPT_WRITE_ASYNC ) str r1, [r4, #NETARM_MEM_CS1_OPTIONS]@ mov r0, #'G'@ bl _printch ldr r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS1_BASE) | \ NETARM_MEM_BAR_DRAM_FP | \ NETARM_MEM_BAR_DRAM_MUX_INT | \ NETARM_MEM_BAR_DRAM_MUX_BAL | \ NETARM_MEM_BAR_DRAM_SEL | \ NETARM_MEM_BAR_BURST_EN | \ NETARM_MEM_BAR_VALID ) str r1, [r4, #NETARM_MEM_CS1_BASE_ADDR]@ mov r0, #'H'@ bl _printch /* CS2 */ ldr r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS2_MASK) | \ NETARM_MEM_OPT_BCYC_3 | \ NETARM_MEM_OPT_BSIZE_4 | \ NETARM_MEM_OPT_WAIT_STATES(0) | \ NETARM_MEM_OPT_32BIT | \ NETARM_MEM_OPT_READ_ASYNC | \ NETARM_MEM_OPT_WRITE_ASYNC ) str r1, [r4, #NETARM_MEM_CS2_OPTIONS]@ mov r0, #'I'@ bl _printch ldr r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS2_BASE) | \ NETARM_MEM_BAR_DRAM_FP | \ NETARM_MEM_BAR_DRAM_MUX_INT | \ NETARM_MEM_BAR_DRAM_MUX_BAL | \ NETARM_MEM_BAR_DRAM_SEL | \ NETARM_MEM_BAR_BURST_EN | \ NETARM_MEM_BAR_VALID ) str r1, [r4, #NETARM_MEM_CS2_BASE_ADDR]@ mov r0, #'J'@ bl _printch#endif/* CS3 */#ifdef CONFIG_NETARM_EEPROM ldr r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS3_MASK) | \ NETARM_MEM_OPT_BCYC_1 |\ NETARM_MEM_OPT_BSIZE_2 | \ NETARM_MEM_OPT_WAIT_STATES(10) | \ NETARM_MEM_OPT_8BIT | \ NETARM_MEM_OPT_READ_ASYNC | \ NETARM_MEM_OPT_WRITE_ASYNC )#else ldr r1, =( 0 )#endif str r1, [r4, #NETARM_MEM_CS3_OPTIONS]@ mov r0, #'K'@ bl _printch #ifdef CONFIG_NETARM_EEPROM ldr r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS3_BASE) | \ NETARM_MEM_BAR_DRAM_FP | \ NETARM_MEM_BAR_DRAM_MUX_INT | \ NETARM_MEM_BAR_DRAM_MUX_BAL | \ NETARM_MEM_BAR_VALID )#else ldr r1, =( 0 )#endif str r1, [r4, #NETARM_MEM_CS3_BASE_ADDR]@ mov r0, #'L'@ bl _printch /* CS4 */ ldr r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS4_MASK) | \ NETARM_MEM_OPT_32BIT_EXT_ACK | \ NETARM_MEM_OPT_READ_ASYNC | \ NETARM_MEM_OPT_WRITE_ASYNC ) str r1, [r4, #NETARM_MEM_CS4_OPTIONS] ldr r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS4_BASE) | \ NETARM_MEM_BAR_DRAM_FP | \ NETARM_MEM_BAR_DRAM_MUX_INT | \ NETARM_MEM_BAR_DRAM_MUX_BAL | \ NETARM_MEM_BAR_VALID ) str r1, [r4, #NETARM_MEM_CS4_BASE_ADDR]#else/* Settings for IMMS' EMLIN board *//* mem config */ ldr r1, =( NETARM_MEM_REFR_PERIOD_USEC(15) | \ NETARM_MEM_CFG_REFRESH_EN | \ NETARM_MEM_CFG_REFR_CYCLE_8CLKS ) str r1, [r4, #NETARM_MEM_MODULE_CONFIG] mov r0, #'D' bl _printch /* CS0 (Flash) */ ldr r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS0_BASE) | \ NETARM_MEM_BAR_DRAM_FP | \ NETARM_MEM_BAR_DRAM_MUX_INT | \ NETARM_MEM_BAR_DRAM_MUX_BAL | \ NETARM_MEM_BAR_VALID ) str r1, [r4, #NETARM_MEM_CS0_BASE_ADDR] mov r0, #'E' bl _printch /* trust that the bus size for flash was strapped correctly */ /* this saves the bus width in r2 and then ORs it back in */ /* it's a pretty safe assumption, otherwise it wouldn't boot */ ldr r2, [r4, #NETARM_MEM_CS0_OPTIONS] and r2, r2, #NETARM_MEM_OPT_BUS_SIZE_MASK ldr r1, =( NETARM_MEM_OPT_BASE_USE(0xFFC00000) | \ NETARM_MEM_OPT_WAIT_STATES(FLASH_90ns_WAIT_STATES) | \ NETARM_MEM_OPT_BCYC_2 | \ NETARM_MEM_OPT_BSIZE_4 | \ NETARM_MEM_OPT_READ_ASYNC | \ NETARM_MEM_OPT_WRITE_ASYNC ) orr r1, r1, r2 str r1, [r4, #NETARM_MEM_CS0_OPTIONS] mov r0, #'F' bl _printch/* CS1 (SDRAM - optional) */ ldr r1, =( NETARM_MEM_OPT_BASE_USE(0xFF000000) | \ NETARM_MEM_OPT_BCYC_2 | \ NETARM_MEM_OPT_BSIZE_8 | \ NETARM_MEM_OPT_WAIT_STATES(0) | \ NETARM_MEM_OPT_32BIT | \ NETARM_MEM_OPT_READ_ASYNC | \ NETARM_MEM_OPT_WRITE_ASYNC ) str r1, [r4, #NETARM_MEM_CS1_OPTIONS] mov r0, #'G' bl _printch ldr r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS2_BASE) | \ NETARM_MEM_BAR_DRAM_SYNC | \ NETARM_MEM_BAR_DRAM_MUX_INT | \ NETARM_MEM_BAR_DRAM_MUX_UNBAL | \ NETARM_MEM_BAR_DRAM_SEL ) str r1, [r4, #NETARM_MEM_CS1_BASE_ADDR] mov r0, #'H' bl _printch/* CS2 (mainboard SDRAM) */ ldr r1, =( NETARM_MEM_OPT_BASE_USE(0xFF000000) | \ NETARM_MEM_OPT_BCYC_2 | \ NETARM_MEM_OPT_BSIZE_8 | \ NETARM_MEM_OPT_WAIT_STATES(0) | \ NETARM_MEM_OPT_32BIT | \ NETARM_MEM_OPT_READ_ASYNC | \ NETARM_MEM_OPT_WRITE_ASYNC ) str r1, [r4, #NETARM_MEM_CS2_OPTIONS] mov r0, #'I' bl _printch ldr r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS1_BASE) | \ NETARM_MEM_BAR_DRAM_SYNC | \ NETARM_MEM_BAR_DRAM_MUX_INT | \ NETARM_MEM_BAR_DRAM_MUX_UNBAL | \ NETARM_MEM_BAR_DRAM_SEL | \ NETARM_MEM_BAR_VALID ) str r1, [r4, #NETARM_MEM_CS2_BASE_ADDR] mov r0, #'J' bl _printch/* CS3 (Peripherals) */ ldr r1, =( NETARM_MEM_OPT_BASE_USE(0xFFF00000) | \ NETARM_MEM_OPT_BCYC_4 |\ NETARM_MEM_OPT_BSIZE_2 | \ NETARM_MEM_OPT_WAIT_STATES(15) | \ NETARM_MEM_OPT_16BIT | \ NETARM_MEM_OPT_READ_SYNC | \ NETARM_MEM_OPT_WRITE_SYNC ) str r1, [r4, #NETARM_MEM_CS3_OPTIONS] mov r0, #'K' bl _printch ldr r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS3_BASE) | \ NETARM_MEM_BAR_DRAM_FP | \ NETARM_MEM_BAR_DRAM_MUX_INT | \ NETARM_MEM_BAR_1BCLK_IDLE | \ NETARM_MEM_BAR_DRAM_MUX_BAL | \ NETARM_MEM_BAR_VALID ) str r1, [r4, #NETARM_MEM_CS3_BASE_ADDR] mov r0, #'L' bl _printch/* CS4 (FPGA) */ ldr r1, =( NETARM_MEM_OPT_BASE_USE(0xFFFFF000) | \ NETARM_MEM_OPT_WAIT_STATES(15) | \ NETARM_MEM_OPT_32BIT | \ NETARM_MEM_OPT_READ_SYNC | \ NETARM_MEM_OPT_WRITE_SYNC ) str r1, [r4, #NETARM_MEM_CS4_OPTIONS] ldr r1, =( 0x30000000 | \ NETARM_MEM_BAR_DRAM_FP | \ NETARM_MEM_BAR_DRAM_MUX_INT | \ NETARM_MEM_BAR_1BCLK_IDLE | \ NETARM_MEM_BAR_DRAM_MUX_BAL | \ NETARM_MEM_BAR_VALID ) str r1, [r4, #NETARM_MEM_CS4_BASE_ADDR]#endif/* copy to RAM */ mov r0, #'M' bl _printch mov r3, #NETARM_MMAP_RAM_BASE; mov r4, #NETARM_MMAP_FLASH_BASE; mov r0, #NETARM_MMAP_FLASH_COPY_SIZE;1: ldr r1, [r4], #4 str r1, [r3], #4 subs r0, r0, #4 bgt 1b_exec_in_RAM: mov r0, #'N' bl _printch ldr pc, =(__zentry)__zentry:/* * print bootloaded hello and current PC */ mov r0, #'@' bl _printch mov r0, pc bl _printhex8 mov r0, #'\n' bl _printch ldr r0, =_hello_world bl _printascii mov r0, #'\n' bl _printch/* * dump serial and memory control registers */ bl _netarm_debug_serial_dump bl _netarm_debug_mem_ctl_dump /* * count down to boot... */ mov r8, #151: mov r0, r8 bl _printhex2 mov r0, #'\r' bl _printch mov r2, #0x200002: subs r2, r2, #1 bgt 2b subs r8, r8, #1 bgt 1b/* * test point - jump to blink *//* b _netarm_led_blink *//* * set up initial stack */ ldr r5, =LC0 ldmia r5, {r5, r6, r8, r9, sp}/* clear BSS segment */ mov r4, #01: cmp r5, r8 strcc r4, [r5], #4 bcc 1b /* Put initial values into stack. This would normally be done by sched_init() in kernel/sched.c, but that would overwrite the stack we're already using. That would be bad. (code from the DSC21 head file by Steve Johnson) Only fill half the task_union area, because the task list starts in the lower part. --rp */ mov r5, sp sub r5, r5, #0x1000 ldr r4, L_STACK_MAGIC str r4, [r5], #4 ldr r4, L_STACK_UNTOUCHED_MAGIC1: cmp r5, sp strcc r4, [r5], #4 bcc 1b/* * Stob in the ARMID - since we don't have CP15 to query... */ ldr r2, =0x41007700 str r2, [r6]/* Pretend we know what our processor code is (for arm_id) */ mov r2, #MACH_TYPE_NETARM str r2, [r9]/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -