imx23_olinuxino_start.S revision 1.1
11.1Sjkunz/* $Id: imx23_olinuxino_start.S,v 1.1 2012/11/20 19:08:46 jkunz Exp $ */
21.1Sjkunz
31.1Sjkunz/*
41.1Sjkunz * Copyright (c) 2012 The NetBSD Foundation, Inc.
51.1Sjkunz * All rights reserved.
61.1Sjkunz *
71.1Sjkunz * This code is derived from software contributed to The NetBSD Foundation
81.1Sjkunz * by Petri Laakso.
91.1Sjkunz *
101.1Sjkunz * Redistribution and use in source and binary forms, with or without
111.1Sjkunz * modification, are permitted provided that the following conditions
121.1Sjkunz * are met:
131.1Sjkunz * 1. Redistributions of source code must retain the above copyright
141.1Sjkunz *    notice, this list of conditions and the following disclaimer.
151.1Sjkunz * 2. Redistributions in binary form must reproduce the above copyright
161.1Sjkunz *    notice, this list of conditions and the following disclaimer in the
171.1Sjkunz *    documentation and/or other materials provided with the distribution.
181.1Sjkunz *
191.1Sjkunz * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
201.1Sjkunz * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
211.1Sjkunz * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
221.1Sjkunz * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
231.1Sjkunz * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
241.1Sjkunz * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
251.1Sjkunz * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
261.1Sjkunz * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
271.1Sjkunz * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
281.1Sjkunz * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
291.1Sjkunz * POSSIBILITY OF SUCH DAMAGE.
301.1Sjkunz */
311.1Sjkunz
321.1Sjkunz#include <machine/asm.h>
331.1Sjkunz#include <machine/pmap.h>
341.1Sjkunz#include <arm/armreg.h>
351.1Sjkunz#include <arm/imx/imx23var.h>
361.1Sjkunz#include <arm/imx/imx23_uartdbgreg.h>
371.1Sjkunz
381.1Sjkunz.section .start,"ax",%progbits
391.1Sjkunz
401.1Sjkunz.global	_C_LABEL(olinuxino_start)
411.1Sjkunz_C_LABEL(olinuxino_start):
421.1Sjkunz
431.1Sjkunz	/*
441.1Sjkunz	 * Set up the first level page table. The page table has 4096 section
451.1Sjkunz	 * page table entries which each one maps 1MB of virtual memory.
461.1Sjkunz	 * Section entries are mapped from mmu_init_table to the page table.
471.1Sjkunz	 */
481.1Sjkunz	l1pt_p	.req r0
491.1Sjkunz	mit_p	.req r1
501.1Sjkunz	va	.req r2
511.1Sjkunz	pa	.req r3
521.1Sjkunz	n_sec	.req r4
531.1Sjkunz	attr	.req r5
541.1Sjkunz	pte_p	.req r6
551.1Sjkunz	sec	.req r7
561.1Sjkunz	tmp	.req r8
571.1Sjkunz	tmp2	.req r9
581.1Sjkunz
591.1Sjkunz	ldr	l1pt_p, Ll1_pt
601.1Sjkunz
611.1Sjkunz	/* Zero the page table. */
621.1Sjkunz	mov	tmp, #0
631.1Sjkunz	add	tmp2, l1pt_p, #L1_TABLE_SIZE
641.1Sjkunz1:	str	tmp, [l1pt_p], #4
651.1Sjkunz	cmp	l1pt_p, tmp2
661.1Sjkunz	blt	1b
671.1Sjkunz
681.1Sjkunz	ldr	l1pt_p, Ll1_pt
691.1Sjkunz
701.1Sjkunz	/* Map sections. */
711.1Sjkunz	ldr	mit_p, =mmu_init_table
721.1Sjkunz	ldmia	mit_p!, {va, pa, n_sec, attr}
731.1Sjkunz
741.1Sjkunz	/*
751.1Sjkunz	 * Calculate PTE addresses for a MVA's.
761.1Sjkunz	 *
771.1Sjkunz	 * Bits[31:14] of the Translation Table Base register are concatenated
781.1Sjkunz	 * with bits[31:20] of the modified virtual address and two zero bits
791.1Sjkunz	 * to produce a physical address of the page table entry for a MVA:
801.1Sjkunz	 *
811.1Sjkunz	 * PTE = (TTBR & 0xffffc000) | ((MVA & 0xfff00000)>>18)
821.1Sjkunz	 */
831.1Sjkunz3:	ldr	tmp, =0xffffc000
841.1Sjkunz	and	pte_p, l1pt_p, tmp
851.1Sjkunz	ldr	tmp, =0xfff00000
861.1Sjkunz	and	va, va, tmp
871.1Sjkunz	mov	va, va, LSR #18
881.1Sjkunz	orr	pte_p, pte_p, va
891.1Sjkunz
901.1Sjkunz2:	orr	sec, pa, attr
911.1Sjkunz	str	sec, [pte_p], #4	/* Store #n_sec sections to the page */
921.1Sjkunz	add	pa, pa, #0x100000	/* table. */
931.1Sjkunz	subs	n_sec, #1
941.1Sjkunz	bne	2b
951.1Sjkunz
961.1Sjkunz	ldmia	mit_p!, {va, pa, n_sec, attr}
971.1Sjkunz	cmp	n_sec, #0
981.1Sjkunz	bne	3b
991.1Sjkunz
1001.1Sjkunz	/*
1011.1Sjkunz	 * The Translation Table Base Register holds the physical address of
1021.1Sjkunz	 * the page table.
1031.1Sjkunz	 */
1041.1Sjkunz	mcr	p15, 0, l1pt_p, c2, c0, 0
1051.1Sjkunz
1061.1Sjkunz	.unreq	l1pt_p
1071.1Sjkunz	.unreq	mit_p
1081.1Sjkunz	.unreq	va
1091.1Sjkunz	.unreq	pa
1101.1Sjkunz	.unreq	n_sec
1111.1Sjkunz	.unreq	attr
1121.1Sjkunz	.unreq	pte_p
1131.1Sjkunz	.unreq	sec
1141.1Sjkunz	.unreq	tmp
1151.1Sjkunz	.unreq	tmp2
1161.1Sjkunz
1171.1Sjkunz	/*
1181.1Sjkunz	 * Sections are in domain 0 and we set D0 access control to client
1191.1Sjkunz	 * mode, which means AP bits are checked. Since we are running
1201.1Sjkunz	 * privileged mode and APs are kernel read/write, access is granted.
1211.1Sjkunz	 */
1221.1Sjkunz	mov	r0, #DOMAIN_CLIENT<<(PMAP_DOMAIN_KERNEL*2)
1231.1Sjkunz	mcr	p15, 0, r0, c3, c0, 0
1241.1Sjkunz
1251.1Sjkunz	/*
1261.1Sjkunz	 * Enable the MMU.
1271.1Sjkunz	 */
1281.1Sjkunz	mov	r0, #0
1291.1Sjkunz	mcr	p15, 0, r0, c8, c7, 0	/* Invalidate TLB. */
1301.1Sjkunz
1311.1Sjkunz	mrc	p15, 0, r0, c1, c0, 0
1321.1Sjkunz	ldr	r1, =(CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE \
1331.1Sjkunz			| CPU_CONTROL_AFLT_ENABLE | CPU_CONTROL_MMU_ENABLE)
1341.1Sjkunz	orr	r0, r0, r1
1351.1Sjkunz	mcr	p15, 0, r0, c1, c0, 0
1361.1Sjkunz	nop	/* Fetch flat. */
1371.1Sjkunz	nop	/* Fetch flat. */
1381.1Sjkunz
1391.1Sjkunz	/*
1401.1Sjkunz	 * Jump to start in locore.S. start sets the sp point to DRAM, zeroes
1411.1Sjkunz	 * the .bss and calls initarm. start never returns.
1421.1Sjkunz	 */
1431.1Sjkunz	ldr	pc, =start
1441.1Sjkunz
1451.1Sjkunz	/* NOTREACHED */
1461.1Sjkunz
1471.1Sjkunz/*
1481.1Sjkunz * Initial first level translation table on a 16kB boundary located at the
1491.1Sjkunz * end of the DRAM.
1501.1Sjkunz *
1511.1Sjkunz * The translation table has 4096 32-bit section entries, each describing 1MB of
1521.1Sjkunz * virtual memory which means 4GB of virtual memory to be addressed.
1531.1Sjkunz */
1541.1SjkunzLl1_pt:
1551.1Sjkunz	.word (DRAM_BASE + MEMSIZE * 1024 * 1024 - L1_TABLE_SIZE)
1561.1Sjkunz
1571.1Sjkunz#define MMU_INIT(va,pa,n_sec,attr)					\
1581.1Sjkunz	.word va;							\
1591.1Sjkunz	.word pa;							\
1601.1Sjkunz	.word n_sec;							\
1611.1Sjkunz	.word attr;
1621.1Sjkunz
1631.1Sjkunzmmu_init_table:
1641.1Sjkunz	/* On-chip RAM */
1651.1Sjkunz	MMU_INIT(0x00000000, 0x00000000,
1661.1Sjkunz		1,
1671.1Sjkunz		L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_PROTO)
1681.1Sjkunz
1691.1Sjkunz	/* On-chip ROM (Vectors) */
1701.1Sjkunz	MMU_INIT(0xFFFF0000, 0xFFFF0000,
1711.1Sjkunz		1,
1721.1Sjkunz		L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_PROTO)
1731.1Sjkunz
1741.1Sjkunz	/* DRAM */
1751.1Sjkunz	MMU_INIT(KERNEL_BASE_virt, KERNEL_BASE_phys,
1761.1Sjkunz		MEMSIZE,
1771.1Sjkunz		L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_C |\
1781.1Sjkunz			L1_S_B | L1_S_PROTO)
1791.1Sjkunz
1801.1Sjkunz	/* Peripherals */
1811.1Sjkunz	MMU_INIT(APBH_BASE, APBH_BASE,
1821.1Sjkunz		1,
1831.1Sjkunz		L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_PROTO)
1841.1Sjkunz
1851.1Sjkunz	MMU_INIT(0, 0, 0, 0)
186