www.pudn.com > mizi_vivi.rar > head.S
/* * vivi/arch/sa1100/head.S: initialise hardware * * Copyright (C) 2001 MIZI Research, Inc. * * 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 * * * Author: Janghoon Lyu* Date : $Date: 2002/09/12 05:27:40 $ * * $Revision: 1.7 $ * * * History: * * 2001-10-23: Janghoon Lyu * - Initial code * - Based on bootldr/boot-sa1100.s * * 2002-02-01: Janghoon Lyu * - Clean-up * * 2002-07-10: Janghoon Lyu * - »õ·Î¿î ¸¶À½À¸·Î »õ·Ó°Ô ÀÛ¼ºÇÕ´Ï´Ù. * * 2002-07-11: Janghoon Lyu * - ½Ã½ºÅÛ ¸®¼Â ÇÒ ¶§, ½Ã¸®¾ó Ãâ·Â¿¡ ¹®Á¦°¡ ÀÖ´Â °ÍÀ» ÇØ°á * ¾à°£ÀÇ µô·¹À̸¦ ÁÖ¾úÀ½. * - Wakeup Äڵ忡¼ ½Ã¸®¾ó Ãâ·Â¹® Á¦°Å. * ¸¸¾à¿¡ »ç¿ëÇÏ°í ½ÍÀ¸¸é InitUART¸¦ ºÒ·¯¼ ¿ÏÀüÈ÷ ½Ã¸®¾óÀ» * ÃʱâÈ ÇØÁà¾ß µÉ °Í °°À½. * */ #define ENTRY(name) .globl name; \ name: #include "config.h" #include "machine.h" #include "sizes.h" @ Start of executable coes ENTRY(_start) ENTRY(ResetEntryPoint) @ @ Exception vector table (physical address = 0x00000000) @ @ 0x00: Reset b Reset @ 0x04: Undefined instruction exception UndefEntryPoint: b HandleUndef @ 0x08: Software interrupt exception SWIEntryPoint: b HandleSWI @ 0x0c: Prefetch Abort (Instruction Fetch Memory Abort) PrefetchAbortEntryPoint: b HandlePrefetchAbort @ 0x10: Data Access Memory Abort DataAbortEntryPoint: b HandleDataAbort @ 0x14: Not used NotUsedEntryPoint: b HandleNotUsed @ 0x18: IRQ(Interrupt Request) exception IRQEntryPoint: b HandleIRQ @ 0x1c: FIQ(Fast Interrupt Request) exception FIQEntryPoint: b HandleFIQ @ @ VIVI Magic @ @ 0x20: magic number so we can verify that we only put .long 0x0 @ 0x24: .long 0x0 @ 0x28: where this vivi was linked, so we can put it in memory in the right place .long _start @ 0x2C: this contains the platform, cpu and machine id .long ARCHITECTURE_MAGIC @ 0x30 vivi capabilities .long 0 @ @ Start VIVI head. @ Reset: @ Disable all interrupts ldr r1, SA1100_ICMR_ADDRESS mov r0, #0 str r0, [r1, #0] #if 0 @ Put us in the right frame of mind ... msr cpsr_c, #(F_BIT | I_BIT | SVC_MODE) #endif @ Set clock speed to correct speed ldr r1, SA1100_PPCR_ADDRESS mov r0, #SA1100_PPCR_206MHZ str r0, [r1, #0] @ Setup memory bl MemSetup #ifdef CONFIG_PM @ Check if this is a wake-up from sleep ldr r1, SA1100_RCSR_ADDRESS ldr r0, [r1, #0] and r0, r0, #(RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR) teq r0, #RCSR_SMR beq WakeupStart #endif @ Initialize the UARTs @ Wait for a while. mov r1, #0x10000 2: subs r1, r1, #1 bne 2b #ifdef CONFIG_SERIAL_UART1 bl InitUART1 #elif defined(CONFIG_SERIAL_UART3) bl InitUART3 #endif #ifdef CONFIG_DEBUG_LL @ Print currunt Program Counter mov r0, #'\r' ldr r1, SerBase bl PrintChar mov r0, #'\n' ldr r1, SerBase bl PrintChar mov r0, #'@' ldr r1, SerBase bl PrintChar mov r0, pc ldr r1, SerBase bl PrintHexWord #endif @ Setup stack, Ready to call C functions #ifdef CONFIG_DEBUG_LL ldr r0, STR_STACK bl PrintWord ldr r0, DW_STACK_START bl PrintHexWord #endif @ Go Go Go ldr sp,DW_STACK_START mov fp, #0 @ no previous frame, so fp=0 mov a2, #0 @ set argv to NULL bl main @ call main mov pc, #FLASH_BASE @ ohterwise, reboot @ @ End VIVI head @ @ @ Wakup-up codes @ #ifdef CONFIG_PM WakeupStart: #ifdef CONFIG_SA1100_ENDA @ This is tweak for hardware. The EnDA requires to initialize @ UARTs when it wake-up from sleep mode. bl InitUART1 bl InitUART3 #endif @ Clear sleep reset bit ldr r1, SA1100_RCSR_ADDRESS mov r0, #RCSR_SMR str r0, [r1] ldr r1, SA1100_PSSR_ADDRESS mov r0, #PSSR_PH str r0, [r1, #0] ldr r1, SA1100_PSSR_ADDRESS mov r0, #PSSR_DH str r0, [r1, #0] @ Clearing DRAM hold @ Wake-up DRAM mov r1, #SA1100_DRAM_CONFIGURATION_BASE ldr r0, [r1, #SA1100_MDREFR] @ Mask out all of the bits that are undefined after a reset ldr r2, mdrefr_valid_bits_after_reset and r0, r0, r2 @ Disable auto power down bic r0, r0, #MDREFR_EAPD | MDREFR_KAPD @ Set KnRUN (from Self-refresh and Clock-stop to Self-refresh) orr r0, r0, #MDREFR_K1RUN str r0, [r1, #SA1100_MDREFR] @ Clear SLFRSH (from Self-refresh to Power-down) bic r0, r0, #MDREFR_SLFRSH str r0, [r1, #SA1100_MDREFR] @ Set E1PIN (from Power-down to PWRDNX) orr r0, r0, #MDREFR_E1PIN str r0, [r1, #SA1100_MDREFR] ldr r0, dram_cas0_waveform0 str r0, [r1, #SA1100_MDCAS00] ldr r0, dram_cas0_waveform1 str r0, [r1, #SA1100_MDCAS01] ldr r0, dram_cas0_waveform2 str r0, [r1, #SA1100_MDCAS02] ldr r0, dram_mdrefr str r0, [r1, #SA1100_MDREFR] @ init the memory controller mode config register ldr r0, dram_mdcnfg str r0, [r1, #SA1100_MDCNFG] mov r1, #0xC0000000 ldr r0, [r1], #4 ldr r0, [r1], #4 ldr r0, [r1], #4 ldr r0, [r1], #4 ldr r0, [r1], #4 ldr r0, [r1], #4 ldr r0, [r1], #4 ldr r0, [r1], #4 ldr r0, [r1, #SA1100_MDCNFG] bic r0, r0, #MDCNFG_BANK0_ENABLE str r0, [r1, #SA1100_MDCNFG] mov r1, #0xC0000000 ldr r0, [r1], #4 ldr r0, [r1], #4 ldr r0, [r1], #4 ldr r0, [r1], #4 ldr r0, [r1], #4 ldr r0, [r1], #4 ldr r0, [r1], #4 ldr r0, [r1], #4 mov r1, #SA1100_DRAM_CONFIGURATION_BASE ldr r0, [r1, #SA1100_MDCNFG] orr r0, r0, #MDCNFG_BANK0_ENABLE str r0, [r1, #SA1100_MDCNFG] @ Enable SDRAM auto power down ldr r0, dram_mdrefr orr r0, r0, #(MDREFR_EAPD + MDREFR_KAPD) str r0, [r1, #SA1100_MDREFR] WakeUp: ldr r7, SA1100_PSPR_ADDRESS ldr r6, [r7, #0] mov pc, r6 #endif @ @ MemSetup - setup SDRAM @ ENTRY(MemSetup) mov r1, #SA1100_DRAM_CONFIGURATION_BASE @ initialise the static memory timing ldr r2, msc2_config str r2, [r1, #SA1100_MSC2] ldr r2, msc1_config str r2, [r1, #SA1100_MSC1] ldr r2, msc0_config ldr r3, [r1, #SA1100_MSC0] @ save the current bit value and r3, r3, #MSC_RBW16 @ make sure the bit is cleared in the new config word bic r2, r2, #MSC_RBW16 @ propagate the bit into the new config value orr r2, r3, r2 str r2, [r1, #SA1100_MSC0] @ disable synchronous rom because we have none mov r2, #0 str r2, [r1, #SA1100_SMCNFG] @ configutre the expansion (PCMCIA) memory ldr r2, mecr_config str r2, [r1, #SA1100_MECR] @ Set up the DRAM in banks 0 and 1 [1] 10.3 ldr r2, dram_cas0_waveform0 str r2, [r1, #SA1100_MDCAS00] ldr r2, dram_cas0_waveform1 str r2, [r1, #SA1100_MDCAS01] ldr r2, dram_cas0_waveform2 str r2, [r1, #SA1100_MDCAS02] ldr r2, dram_mdrefr str r2, [r1, #SA1100_MDREFR] ldr r2, dram_mdcnfg str r2, [r1, #SA1100_MDCNFG] mov pc, lr /* All done, return*/ @ @ Initialise Serial @ @ SA1110 has two UART ports @ @ InitUART1 - Initialize Serial Communications @ Following reset, the UART is disabled. So, we do the following: InitUART1: #ifdef CONFIG_SA1100_GILL ldr r1, BCR_BASE mov r2, #GILL_BCR_RS232_ON str r2, [r1, #0] #endif @ Now clear all 'sticky' bits in serial I registers, cf. [1] 11.11 ldr r1, SDLCBase mov r2, #0x01 str r2, [r1] ldr r1, Ser1Base mov r2, #0xFF str r2, [r1, #SA1100_UTSR0] @ UART1 Status Reg. 0 @ disable the UART mov r2, #0x00 str r2, [r1, #SA1100_UTCR3] @ UART1 Control Reg. 3 @ Set the serial port to sensible defaults: @ no break, no interrupts, no parity, 8 databits, 1 stopbit. mov r2, #SA1100_UTCR0_8BIT str r2, [r1, #SA1100_UTCR0] @ UART1 Control Reg. 0 #define UART_BRD ((3686400 / 16 / UART_BAUD_RATE) - 1) mov r2, #((UART_BRD >> 16) & 0xF) str r2, [r1, #SA1100_UTCR1] mov r2, #(UART_BRD & 0xFF) str r2, [r1, #SA1100_UTCR2] @ enable the UART TX and RX InitUart1Enable: mov r2, #(SA1100_UTCR3_RXE|SA1100_UTCR3_TXE) str r2, [r1, #SA1100_UTCR3] mov pc, lr /* All done, return*/ @ InitUART3 - Initialize Serial Communications @ Following reset, the UART is disabled. So, we do the following: InitUART3: #ifdef CONFIG_SA1100_GILL ldr r1, BCR_BASE mov r2, #GILL_BCR_RS232_ON str r2, [r1, #0] #endif ldr r1, Ser3Base @ disable the UART mov r2, #0x00 str r2, [r1, #SA1100_UTCR3] @ UART1 Control Reg. 3 @ Now clear all 'sticky' bits in serial I registers, cf. [1] 11.11 mov r2, #0xFF str r2, [r1, #SA1100_UTSR0] @ UART1 Status Reg. 0 @ Set the serial port to sensible defaults: @ no break, no interrupts, no parity, 8 databits, 1 stopbit. mov r2, #SA1100_UTCR0_8BIT str r2, [r1, #SA1100_UTCR0] @ UART1 Control Reg. 0 #define UART_BRD ((3686400 / 16 / UART_BAUD_RATE) - 1) mov r2, #((UART_BRD >> 16) & 0xF) str r2, [r1, #SA1100_UTCR1] mov r2, #(UART_BRD & 0xFF) str r2, [r1, #SA1100_UTCR2] @ enable the UART TX and RX InitUart3Enable: mov r2, #(SA1100_UTCR3_RXE|SA1100_UTCR3_TXE) str r2, [r1, #SA1100_UTCR3] mov pc, lr /* All done, return*/ @ @ Exception handling functions @ HandleUndef: #ifdef CONFIG_DEBUG_LL mov r12, r14 ldr r0, STR_UNDEF ldr r1, SerBase bl PrintWord bl PrintFaultAddr #endif 1: b 1b @ infinite loop HandleSWI: #ifdef CONFIG_DEBUG_LL mov r12, r14 ldr r0, STR_SWI ldr r1, SerBase bl PrintWord bl PrintFaultAddr #endif 1: b 1b @ infinite loop HandlePrefetchAbort: #ifdef CONFIG_DEBUG_LL mov r12, r14 ldr r0, STR_PREFETCH_ABORT ldr r1, SerBase bl PrintWord bl PrintFaultAddr #endif 1: b 1b @ infinite loop HandleDataAbort: #ifdef CONFIG_DEBUG_LL mov r12, r14 ldr r0, STR_DATA_ABORT ldr r1, SerBase bl PrintWord bl PrintFaultAddr #endif 1: b 1b @ infinite loop HandleIRQ: #ifdef CONFIG_DEBUG_LL mov r12, r14 ldr r0, STR_IRQ ldr r1, SerBase bl PrintWord bl PrintFaultAddr #endif 1: b 1b @ infinite loop HandleFIQ: #ifdef CONFIG_DEBUG_LL mov r12, r14 ldr r0, STR_FIQ ldr r1, SerBase bl PrintWord bl PrintFaultAddr #endif 1: b 1b @ infinite loop HandleNotUsed: #ifdef CONFIG_DEBUG_LL mov r12, r14 ldr r0, STR_NOT_USED ldr r1, SerBase bl PrintWord bl PrintFaultAddr #endif 1: b 1b @ infinite loop @ End excepting handling functions @ @ Low Level Debug @ #ifdef CONFIG_DEBUG_LL @ PrintFaultAddr: Print fault address @ @ r12: contains address of instruction + 4 PrintFaultAddr: mov r0, r12 @ Print address of instruction + 4 ldr r1, SerBase bl PrintHexWord mrc p15, 0, r0, c6, c0, 0 @ Read fault virtual address ldr r1, SerBase bl PrintHexWord mov pc, lr @ PrintHexNibble -- prints the least-significant nibble in R0 as a @ hex digit @ r0 contains nibble to write as Hex @ r1 contains base of serial port @ writes r0 with RXSTAT, modifies r0,r2 @ Falls through to PrintChar PrintHexNibble: adr r2, HEX_TO_ASCII_TABLE and r0, r0, #0xF ldr r0, [r2,r0] /* convert to ascii */ b PrintChar @ PrintChar -- prints the character in R0 @ r0 contains the character @ r1 contains base of serial port @ writes r0 with UTSR1, modifies r0,r1,r2 PrintChar: TXBusy: ldr r2,[r1,#SA1100_UTSR1]/* check status*/ tst r2,#SA1100_UTSR1_TNF /* TX not full */ beq TXBusy str r0,[r1,#SA1100_UTDR] ldr r0,[r1,#SA1100_UTSR1] mov pc, lr @ PrintWord -- prints the 4 characters in R0 @ r0 contains the binary word @ r1 contains the base of the serial por @ writes r0 with RXSTAT, modifies r1,r2,r3,r4 PrintWord: mov r3, r0 mov r4, lr bl PrintChar mov r0,r3,LSR #8 /* shift word right 8 bits*/ bl PrintChar mov r0,r3,LSR #16 /* shift word right 16 bits*/ bl PrintChar mov r0,r3,LSR #24 /* shift word right 24 bits*/ bl PrintChar mov r0, #'\r' bl PrintChar mov r0, #'\n' bl PrintChar mov pc, r4 @ PrintHexWord -- prints the 4 bytes in R0 as 8 hex ascii characters @ followed by a newline @ r0 contains the binary word @ r1 contains the base of the serial port @ Writes r0 with RXSTAT, modifies r1,r2,r3,r4 PrintHexWord: mov r4, lr mov r3, r0 mov r0, r3,LSR #28 bl PrintHexNibble mov r0, r3,LSR #24 bl PrintHexNibble mov r0, r3,LSR #20 bl PrintHexNibble mov r0, r3,LSR #16 bl PrintHexNibble mov r0, r3,LSR #12 bl PrintHexNibble mov r0, r3,LSR #8 bl PrintHexNibble mov r0, r3,LSR #4 bl PrintHexNibble mov r0, r3 bl PrintHexNibble mov r0, #'\r' bl PrintChar mov r0, #'\n' bl PrintChar mov pc, r4 #endif @ @ Data Area @ head.S ¿¡¼ »ç¿ëÇÏ´Â µ¥ÀÌÅ͵éÀ» ¸ð¾Æ ³õÀº °÷. @ head.S°¡ ROM¿¡¼ µ¹±â À§Çؼ Çʼö ÀûÀÓ @ @ @ Memory Configuration Data @ .align 4 dram_mdcnfg_enable: .long DRAM_MDCNFG_ENABLE dram_mdcnfg: .long DRAM_MDCNFG dram_cas0_waveform0: .long DRAM_CAS0_WAVEFORM0 dram_cas0_waveform1: .long DRAM_CAS0_WAVEFORM1 dram_cas0_waveform2: .long DRAM_CAS0_WAVEFORM2 dram_mdrefr: .long DRAM_MDREFR msc0_config: .long MSC0_CONFIG msc1_config: .long MSC1_CONFIG msc2_config: .long MSC2_CONFIG mecr_config: .long MECR_CONFIG mdrefr_valid_bits_after_reset: .long MDREFR_SLFRSH|MDREFR_KAPD|MDREFR_EAPD|MDREFR_K2DB2|MDREFR_K1RUN|MDREFR_E1PIN|MDREFR_K0DB2 .align 2 DW_STACK_START: .word STACK_BASE+STACK_SIZE-4 #ifdef CONFIG_DEBUG_LL .align 2 HEX_TO_ASCII_TABLE: .ascii "0123456789ABCDEF" STR_STACK: .ascii "STKP" STR_MTST: .ascii "MTST" STR_UNDEF: .ascii "UNDF" STR_SWI: .ascii "SWI " STR_PREFETCH_ABORT: .ascii "PABT" STR_DATA_ABORT: .ascii "DABT" STR_IRQ: .ascii "IRQ " STR_FIQ: .ascii "FIQ" STR_NOT_USED: .ascii "NUSD" #endif @ @ Serial @ .align 4 SDLCBase: .long SA1100_SDLCBASE Ser1Base: .long SA1100_UART1BASE Ser3Base: .long SA1100_UART3BASE SerBase: #if defined(CONFIG_SERIAL_UART1) .long SA1100_UART1BASE #elif defined(CONFIG_SERIAL_UART3) .long SA1100_UART3BASE #else #error not defined base address of serial #endif @ @ Control registers @ SA1100_PPCR_ADDRESS: .long SA1100_PPCR_REG SA1100_ICMR_ADDRESS: .long SA1100_ICMR_REG @ @ Power Management @ #ifdef CONFIG_PM SA1100_RCSR_ADDRESS: .long SA1100_RCSR_REG SA1100_PSSR_ADDRESS: .long SA1100_PSSR_REG SA1100_PSPR_ADDRESS: .long SA1100_PSPR_REG #endif @ @ Hardware dependent @ #ifdef CONFIG_SA1100_GILL BCR_BASE: .long GILL_BCR_BASE #endif