Home | History | Annotate | Line # | Download | only in armadillo
armadillo9_start.S revision 1.2
      1 /*	$NetBSD: armadillo9_start.S,v 1.2 2006/02/06 14:03:22 hamajima Exp $ */
      2 
      3 /*
      4  * Copyright (c) 2003
      5  *	Ichiro FUKUHARA <ichiro (at) ichiro.org>.
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. All advertising materials mentioning features or use of this software
     17  *    must display the following acknowledgement:
     18  *	This product includes software developed by Ichiro FUKUHARA.
     19  * 4. The name of the company nor the name of the author may be used to
     20  *    endorse or promote products derived from this software without specific
     21  *    prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR
     24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     26  * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
     27  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  */
     35 #include <machine/asm.h>
     36 #include <arm/armreg.h>
     37 #include <arm/arm32/pte.h>
     38 
     39 	.section .start,"ax",%progbits
     40 
     41 	.global	_C_LABEL(armadillo9_start)
     42 _C_LABEL(armadillo9_start):
     43 
     44 	/* make sure svc mode and all fiqs&irqs disabled */
     45 	mov	r0, #(PSR_SVC32_MODE | I32_bit | F32_bit)
     46 	msr	cpsr_c, r0
     47 
     48 	/*
     49 	 * We will go ahead and disable the MMU here so that we don't
     50 	 * have to worry about flushing caches, etc.
     51 	 *
     52 	 * Note that we may not currently be running VA==PA, which means
     53 	 * we'll need to leap to the next insn after disabing the MMU.
     54 	 */
     55 	adr	r8, Lunmapped
     56 	bic	r8, r8, #0xff000000	/* clear upper 8 bits */
     57 	orr	r8, r8, #0xc0000000	/* OR in physical base address */
     58 
     59 	/*
     60 	 * Setup coprocessor 15.
     61 	 */
     62 	mrc	p15, 0, r2, c1, c0, 0
     63 	bic	r2, r2, #CPU_CONTROL_MMU_ENABLE
     64 	bic	r2, r2, #CPU_CONTROL_DC_ENABLE
     65 	bic	r2, r2, #CPU_CONTROL_IC_ENABLE
     66 	mcr	p15, 0, r2, c1, c0, 0
     67 
     68 	nop
     69 	nop
     70 	nop
     71 	mov	pc, r8			/* Heave-ho! */
     72 
     73 Lunmapped:
     74 #ifdef VERBOSE_INIT_ARM
     75 	/* set temporary stack pointer */
     76 	adr	sp, Ltable
     77 	ldr	sp, [sp]
     78 
     79 	/* initialize UART */
     80 	bl	init_UART
     81 #endif
     82 	/* copy to virtual address */
     83 	adr	r0, Lsection
     84 	ldmia	r0, {r0, r1, r2}	/* r0: kernel(load) start address */
     85 					/* r1: kernel(virtual) start address */
     86 					/* r2: kernel(virtual) end address */
     87 	sub	r3, r2, r1		/* r3: kernel size */
     88 	add	r4, r0, r3		/* r4: kernel(load) end address */
     89 #ifdef VERBOSE_INIT_ARM
     90 #define	putc(c)	 \
     91 	mov	r5, c	;\
     92 	bl	print_char
     93 	putc(#'c')
     94 	putc(#'o')
     95 	putc(#'p')
     96 	putc(#'y')
     97 	putc(#' ')
     98 	putc(#'f')
     99 	putc(#'r')
    100 	putc(#'o')
    101 	putc(#'m')
    102 	putc(#' ')
    103 	bl	print_r0
    104 	putc(#' ')
    105 	putc(#'t')
    106 	putc(#'o')
    107 	putc(#' ')
    108 	bl	print_r1
    109 	putc(#' ')
    110 	putc(#'s')
    111 	putc(#'i')
    112 	putc(#'z')
    113 	putc(#'e')
    114 	putc(#' ')
    115 	bl	print_r3
    116 	bl	print_cr
    117 #endif
    118 1:
    119 	ldr	r5, [r4], #-4
    120 	str	r5, [r2], #-4
    121 	cmp	r4, r0
    122 	bge	1b
    123 
    124 	/*
    125 	 * We want to construct a memory map that maps us
    126 	 * VA==PA (SDRAM at 0xc0000000). We create these
    127 	 * mappings uncached and unbuffered to be safe.
    128 	 */
    129 	/*
    130 	 * Step 1: Map the entire address space VA==PA.
    131 	 */
    132 	adr	r4, Ltable
    133 	ldr	r0, [r4]			/* r0 = &l1table */
    134 	mov	r1, #(L1_TABLE_SIZE / 4)	/* 4096 entry */
    135 	mov	r2, #(L1_S_SIZE)		/* 1MB / section */
    136 	mov	r3, #(L1_S_AP(AP_KRW))		/* kernel read/write */
    137 	orr	r3, r3, #(L1_TYPE_S)		/* L1 entry is section */
    138 1:
    139 	str	r3, [r0], #0x04
    140 	add	r3, r3, r2
    141 	subs	r1, r1, #1
    142 	bgt	1b
    143 
    144 	/*
    145 	 * Step 2: Map VA 0xf0000000->0xf00fffff to PA 0x80000000->0x800fffff.
    146 	 */
    147 	ldr	r0, [r4]
    148 	add	r0, r0, #(0xf00 * 4)		/* offset to 0xf0000000 */
    149 	mov	r3, #(L1_S_AP(AP_KRW))		/* kernel read/write */
    150 	orr	r3, r3, #(L1_TYPE_S)		/* L1 entry is section */
    151 	orr	r3, r3, #0x80000000
    152 	str	r3, [r0], #4
    153 
    154 	/*
    155 	 * Step 3: Map VA 0xf0100000->0xf02fffff to PA 0x80800000->0x809fffff.
    156 	 */
    157 	mov	r3, #(L1_S_AP(AP_KRW))		/* kernel read/write */
    158 	orr	r3, r3, #(L1_TYPE_S)		/* L1 entry is section */
    159 	orr	r3, r3, #0x80000000
    160 	orr	r3, r3, #0x00800000
    161 	str	r3, [r0], #0x4
    162 	add	r3, r3, r2
    163 	str	r3, [r0], #0x4
    164 
    165 	/* OK!  Page table is set up.  Give it to the CPU. */
    166 	adr	r0, Ltable
    167 	ldr	r0, [r0]
    168 	mcr	p15, 0, r0, c2, c0, 0
    169 
    170 	/* Flush the old TLBs, just in case. */
    171 	mcr	p15, 0, r0, c8, c7, 0
    172 
    173 	/* Set the Domain Access register.  Very important! */
    174 	mov	r0, #1
    175 	mcr	p15, 0, r0, c3, c0, 0
    176 
    177 	/* Get ready to jump to the "real" kernel entry point... */
    178 	ldr	r1, Lstart
    179 	mov	r1, r1			/* Make sure the load completes! */
    180 
    181 	/* OK, let's enable the MMU. */
    182 	mrc	p15, 0, r2, c1, c0, 0
    183 	orr	r2, r2, #CPU_CONTROL_MMU_ENABLE
    184 	mcr	p15, 0, r2, c1, c0, 0
    185 
    186 	nop
    187 	nop
    188 	nop
    189 
    190 	/* CPWAIT sequence to make sure the MMU is on... */
    191 	mrc	p15, 0, r2, c2, c0, 0	/* arbitrary read of CP15 */
    192 	mov	r2, r2			/* force it to complete */
    193 	mov	pc, r1			/* leap to kernel entry point! */
    194 
    195 Ltable:
    196 	.word	armadillo9_start - L1_TABLE_SIZE
    197 
    198 Lstart:
    199 	.word	start
    200 
    201 Lsection:
    202 	.word	.start
    203 	.word	0xc0200000
    204 	.word	__bss_start
    205 
    206 #ifdef VERBOSE_INIT_ARM
    207 #ifndef CONUNIT
    208 #define	CONUNIT	0
    209 #endif
    210 #if CONUNIT == 0
    211 #define	UART_BASE	0x008c0000 /* +0x80000000 */
    212 #elif CONUNIT == 1
    213 #define	UART_BASE	0x008d0000 /* +0x80000000 */
    214 #elif CONUNIT == 2
    215 #define	UART_BASE	0x008e0000 /* +0x80000000 */
    216 #endif
    217 
    218 init_UART:
    219 	stmfd	sp!, {r4, r5, lr}
    220 	mov	r4, #0x80000000
    221 	add	r4, r4, #UART_BASE
    222 	ldr	r5, [r4, #0x08]
    223 	orr	r5, r5, #0x10
    224 	str	r5, [r4, #0x08]	/* enable FIFO */
    225 	mov	r5, #0x01
    226 	str	r5, [r4, #0x14]	/* disable interrupt */
    227 	ldmfd	sp!, {r4, r5, pc}
    228 
    229 print_char:	/* char = r5 */
    230 	stmfd	sp!, {r4, r6, lr}
    231 	mov	r4, #0x80000000
    232 	add	r4, r4, #UART_BASE
    233 1:
    234 	ldr	r6, [r4, #0x18]
    235 	tst	r6, #0x20	/* check TXFF */
    236 	bne	1b
    237 	str	r5, [r4, #0x00]
    238 	ldmfd	sp!, {r4, r6, pc}
    239 
    240 print_cr:
    241 	stmfd	sp!, {r5, lr}
    242 	mov	r5, #0x0d	/* cr */
    243 	bl	print_char
    244 	mov	r5, #0x0a	/* lf */
    245 	bl	print_char
    246 	ldmfd	sp!, {r5, pc}
    247 
    248 print_r0:
    249 	stmfd	sp!, {r0, r4-r7, lr}
    250 	mov	r4, #28
    251 	mov	r6, #0xf
    252 1:
    253 	and	r7, r6, r0, ROR r4
    254 	cmp	r7, #10
    255 	addlt	r5, r7, #'0'
    256 	addge	r5, r7, #('a' - 0x0a)
    257 	bl	print_char
    258 	subs	r4, r4, #4
    259 	bge	1b
    260 	ldmfd	sp!, {r0, r4-r7, pc}
    261 
    262 #define	print_register(reg)	 \
    263 	stmfd	sp!, {r0, lr}	;\
    264 	mov	r0, reg		;\
    265 	bl	print_r0	;\
    266 	ldmfd	sp!, {r0, pc}
    267 
    268 print_r1:
    269 	print_register(r1)
    270 
    271 print_r2:
    272 	print_register(r2)
    273 
    274 print_r3:
    275 	print_register(r3)
    276 
    277 print_r4:
    278 	print_register(r4)
    279 
    280 print_r5:
    281 	print_register(r5)
    282 
    283 print_r6:
    284 	print_register(r6)
    285 
    286 print_r7:
    287 	print_register(r7)
    288 
    289 print_r8:
    290 	print_register(r8)
    291 
    292 print_r9:
    293 	print_register(r9)
    294 
    295 print_r10:
    296 	print_register(r10)
    297 
    298 print_r11:
    299 	print_register(r11)
    300 
    301 print_r12:
    302 	print_register(r12)
    303 #endif
    304