📄 boot-sa1100.s
字号:
b EnableCaches/* * Enable Ser3 Transceiver * r0: number of times to wiggle the enable bit * modifies r0, r1, r2 */EnableUart3Transceiver: ldr r1, EGPIOBase mov r2, #EGPIO_BITSY_RS232_ON str r2, [r1, #0] mov pc, lr /* ;; ******************************************************************** ;; InitUART1 - Initialize Serial Communications ;; ******************************************************************** ;; Following reset, the UART is disabled. So, we do the following: */InitUART1: /* Now clear all 'sticky' bits in serial I registers, cf. [1] 11.11 */ 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] /* transmit a character or two */ mov r2, #'^' str r2, [r1, #SA1100_UTDR] mov r2, #'&' str r2, [r1, #SA1100_UTDR] mov pc, lr /* All done, return*/ /* ;; ******************************************************************** ;; InitUART3 - Initialize Serial Communications ;; ******************************************************************** ;; Following reset, the UART is disabled. So, we do the following: */InitUART3: 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 */ /* Set BRD to 1, for a baudrate of 115K2 ([1] 11.11.4.1) */ /* Set BRD to 3, for a baudrate of 57k6 ([1] 11.11.4.1) */ /* Set BRD to 5, for a baudrate of 38k4 ([1] 11.11.4.1) */ /* Set BRD to 23, for a baudrate of 9k6 ([1] 11.11.4.1) */ mov r2, #0x00 str r2, [r1, #SA1100_UTCR1] mov r2, #1 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] /* transmit a character or two */ mov r2, #'%' str r2, [r1, #SA1100_UTDR] mov r2, #'*' str r2, [r1, #SA1100_UTDR] /* set forceon bit, which is in GPIO U5 */ ldr r3, EGPIOBase mov r2, #(1 << 7) str r2, [r3, #0] mov pc, lr /* All done, return*/ /*; *****************************************************************/ /*; InitMem - initialize SDRAM*/ /*; *****************************************************************/ASENTRY(InitMem) /* Set up the DRAM in banks 0 and 1 [1] 10.3 */ mov r1, #SA1100_DRAM_CONFIGURATION_BASE 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_bitsy str r2, [r1, #SA1100_MDCNFG] mov pc, lr /* All done, return*/ /* ;; ******************************************************************** ;; 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 ;;******************************************************************** */ .globl PrintCharPrintChar: 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 /* ;; ******************************************************************** ;; copy - copies are region from addr in r0 to r1. r2=stopping point ;; r0 contains target region address ;; r1 contains source region address ;; r2 contains region length ;; ******************************************************************** */copy: add r2, r2, r1 /* end of source region in r2 */1: cmp r1,r2 ldrlt r3,[r0],#4 strlt r3,[r1],#4 blt 1b mov pc,lr /* ;; ******************************************************************** ;; zi_init - initializes memory region ;; r0 contains target region start address ;; r1 contains target region size ;; r2 contains value to write ;; ******************************************************************** */zi_init: add r1, r1, r0 /* put end address (exclusive) into r1 */1: cmp r0,r1 strlt r2,[r0],#4 blt 1b mov pc,lr /* ;; ******************************************************************** ;; enableMMU ;; ******************************************************************** */ENTRY(enableMMU) /*; r0 = translation table base*/ ldr r0,DW_MMU_TABLE mcr p15, 0, r0, c2, c0, 0 /*; r0 = domain access control*/ ldr r0,MMU_DOMCTRL mcr p15, 0, r0, c3, c0, 0 /*; enable the MMU*/ mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #1 /* bit 0 of c1 is MMU enable*/#ifdef CACHE_ENABLED orr r0, r0, #4 /* bit 2 of c1 is DCACHE enable*/ orr r0, r0, #8 /* bit 3 of c1 is WB enable*/#endif mcr p15, 0, r0, c1, c0, 0 /* ;; flush the I/D caches ;; c7 == cache control operation register ;; crm==c7 opc2==0 indicates Flush I+D Cache ;; r0 is ignored */ mcr p15, 0, r0, c7, c7, 0x00 /* ;; flush the I+D TLB ;; c8 is TLB operation register ;; crm=c7 opc2==0 indicates Flush I+D TLB ;; r0 is ignored */ mcr p15, 0, r0, c8, c7, 0x00 /*; return*/ mov pc,lr /* ;; ******************************************************************** ;; flushTLB ;; ******************************************************************** */ENTRY(flushTLB) /* ;; flush the I/D caches ;; c7 == cache control operation register ;; crm==c7 opc2==0 indicates Flush I+D Cache ;; r0 is ignored */ mcr p15, 0, r0, c7, c7, 0x00 /* ;; flush the I+D TLB ;; c8 is TLB operation register ;; crm=c7 opc2==0 indicates Flush I+D TLB ;; r0 is ignored */ mcr p15, 0, r0, c8, c7, 0x00 /*;; return*/ mov pc,lr ENTRY(writeBackDcache) /* ;; r0 points to the start of a 16384 byte region of readable ;; data used only for this cache flushingroutine. If this area ;; is to be used by other code, then 32K must be loaded and the ;; flush mcr is not needed. /* /*; return: r0,r1,r2 trashed. data cache is clean*/ add r1,r0,#32768l1: ldr r2,[r0],#32 teq r1, r0 bne l1 mcr p15,0,r0,c7,c6,0 mov pc,lr ENTRY(readCPR1) mrc p15,0,r0,c1,c0,0 mov pc,lr ENTRY(readCPR3) mrc p15,0,r0,c3,c0,0 mov pc,lr /* ;; ******************************************************************** ;; boot - boots into another image. DOES NOT RETURN! ;; r0 = pointer to bootinfo ;; r1 = entry point of kernel ;; ******************************************************************** */ENTRY(boot) /* ;; flush the I+D TLB ;; c8 is TLB operation register ;; crm=c7 opc2==0 indicates Flush I+D TLB ;; r0 is ignored */ mcr p15, 0, r0, c8, c7, 0x00 /* flush I+D TLB */ mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer*/ /*; make sure the pipeline is emptied*/ mov r0,r0 mov r0,r0 mov r0,r0 mov r0,r0 mov pc,r1 /* jump to addr. bootloader is done*/ /* ;; ******************************************************************** ;; bootLinux - boots into another image. DOES NOT RETURN! ;; r0 = must contain a zero or else the kernel loops ;; r1 = architecture type (6 for old kernels, 17 for new) ;; r2 = entry point of kernel ;; ******************************************************************** */ENTRY(bootLinux) mov r10, r1 mov r11, r2 /* ;; flush the I+D TLB ;; c8 is TLB operation register ;; crm=c7 opc2==0 indicates Flush I+D TLB ;; r0 is ignored */ MCR p15, 0, r0, c8, c7, 0x00 /* flush I+D TLB */ MCR p15, 0, r0, c7, c10, 4 /* drain the write buffer*/ MOV r3, #0x130 MCR p15, 0, r3, c1, c0, 0 /* disable the MMU */ /*; make sure the pipeline is emptied*/ MOV r0,#0 MOV r0,r0 MOV r0,r0 MOV r0,r0 adr r2, delayedBreakpointPC mov r0, #0 mov r1, r10 ldr r2, [r2, #0] MOV pc, r11 /* jump to addr. bootloader is done*/ .align 5#ifdef HAS_REBOOT_COMMAND /* * remove reboot command until we make it *really* reboot * things. As it is, doesn't really work or make much sense. */ /* ;; ******************************************************************** ;; reboot - restarts the bootloader. DOES NOT RETURN! ;; ******************************************************************** */ENTRY(reboot) /*; disable the instruction/data write buffer caches*/ mrc p15,0,r2,c1,c0,0 mov r3,#~4 AND r2,r2,r3 mov r3,#~8 AND r2,r2,r3 mov r3,#~0x1000 AND r2,r2,r3 mcr p15,0,r2,c1,c0,0 /* ;; flush the caches ;; flush the I/D caches ;; c7 == cache control operation register ;; crm==c7 opc2==0 indicates Flush I+D Cache ;; r0 is ignored */ mcr p15, 0, r0, c7, c7, 0x00 /* ;; flush the I+D TLB ;; c8 is TLB operation register ;; crm=c7 opc2==0 indicates Flush I+D TLB ;; r0 is ignored */ mcr p15, 0, r0, c8, c7, 0x00 mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer*/ /*; make sure the pipeline is emptied*/ mov r0,r0 mov r0,r0 mov r0,r0 b HiReset#endif /* HAS_REBOOT_COMMAND */ /* ;; ******************************************************************** ;; Data Area ;; ******************************************************************** */ .align 2CRC32POLY: .word 0x04c11db7 .align 2addr_start: .word _C_FUNC(ResetEntryPoint) .align 2ENTRY(HEX_TO_ASCII_TABLE) .ascii "0123456789ABCDEF" .align 2STR_STACK: .ascii "STKP" .align 2DW_STACK_START: .word STACK_BASE+STACK_SIZE-4 .align 2DW_MMU_TABLE: .word MMU_TABLE_START .align 2DW_CACHE_FLUSH_REGION: .word CACHE_FLUSH_BASE .align 2MMU_DOMCTRL: .word 0xFFFFFFFF .align 2STR_MTST: .ascii "MTST" .align 2STR_MB2: .ascii "MBK2" .align 2STR_ENDM: .ascii "ENDM" .align 2STR_PRECACHE: .ascii "PRE$" .align 2STR_POSTCACHE: .ascii "PST$" .align 2STR_PREZERO: .ascii "PREZ" .align 2STR_POSTZERO: .ascii "PSTZ" .align 2STR_POSTFLUSH: .ascii "FLSH" .align 2STR_UNDEF: .ascii "UNDF" .align 2STR_SWI: .ascii "SWI " .align 2STR_PREFETCH_ABORT: .ascii "PABT" .align 2STR_DATA_ABORT: .ascii "DABT" .word 0 .align 2STR_IRQ: .ascii "IRQ " .align 2STR_FIQ: .ascii "FIQ" .align 2STR_NOT_USED: .ascii "NUSD" .align 2STR_MEM_ERROR: .ascii "DRAM ERROR"ENTRY(delayedBreakpointPC) .long 0 /*; ******************************************************************/ .align 4dram_mdcnfg_bitsy: /* DRAM Configuration [1] 10.2 */ /* Bitsy development board uses two banks? KM416S4030C, 12 row address bits, 8 col address bits */ /* Bitsy uses two banks KM416S8030C, 12 row address bits, 9 col address bits */ /* Have to set DRAC0 to 14 row bits or else you only get 8 col bits */ /* read from the formfactor unit configuration registers: 0xF3536257 */ .long (MDCNFG_BANK0_ENABLE | MDCNFG_DTIM0_SDRAM | MDCNFG_DWID0_32B \ | MDCNFG_DRAC0(5) | MDCNFG_TRP0(3) | MDCNFG_TDL0(3) | MDCNFG_TWR0(3)) /* MDCAS settings from [1] Table 10-3 (page 10-18) */dram_cas0_waveform0: .long 0xAAAAAAA7dram_cas0_waveform1: .long 0xAAAAAAAAdram_cas0_waveform2: .long 0xAAAAAAAAdram_mdrefr: .long (MDREFR_TRASR(1) | MDREFR_DRI(512) | MDREFR_E1PIN | MDREFR_K1RUN | MDREFR_K1DB2).align 4SDLCBase: .long SA1100_SDLCBASESer1Base: .long SA1100_UART1BASE .globl Ser3BaseSer3Base: .long SA1100_UART3BASESA1100_PPCR_ADDRESS: .long SA1100_PPCR_REGSA1100_ICMR_ADDRESS: .long SA1100_ICMR_REGEGPIOBase: .long BITSY_EGPIO
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -