imx23_olinuxino_start.S revision 1.2
11.2Smatt/* $Id: imx23_olinuxino_start.S,v 1.2 2013/10/07 17:36:40 matt 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.2Smatt#ifdef DEBUG
371.1Sjkunz#include <arm/imx/imx23_uartdbgreg.h>
381.2Smatt#endif
391.1Sjkunz
401.1Sjkunz.section .start,"ax",%progbits
411.1Sjkunz
421.1Sjkunz.global	_C_LABEL(olinuxino_start)
431.1Sjkunz_C_LABEL(olinuxino_start):
441.1Sjkunz	/*
451.1Sjkunz	 * Set up the first level page table. The page table has 4096 section
461.1Sjkunz	 * page table entries which each one maps 1MB of virtual memory.
471.1Sjkunz	 * Section entries are mapped from mmu_init_table to the page table.
481.1Sjkunz	 */
491.1Sjkunz	l1pt_p	.req r0
501.1Sjkunz	mit_p	.req r1
511.1Sjkunz	va	.req r2
521.1Sjkunz	pa	.req r3
531.1Sjkunz	n_sec	.req r4
541.1Sjkunz	attr	.req r5
551.1Sjkunz	pte_p	.req r6
561.1Sjkunz	sec	.req r7
571.1Sjkunz	tmp	.req r8
581.1Sjkunz	tmp2	.req r9
591.1Sjkunz
601.2Smatt	ldr	l1pt_p, .Ll1_pt
611.1Sjkunz
621.1Sjkunz	/* Zero the page table. */
631.1Sjkunz	mov	tmp, #0
641.1Sjkunz	add	tmp2, l1pt_p, #L1_TABLE_SIZE
651.1Sjkunz1:	str	tmp, [l1pt_p], #4
661.1Sjkunz	cmp	l1pt_p, tmp2
671.1Sjkunz	blt	1b
681.1Sjkunz
691.2Smatt	ldr	l1pt_p, .Ll1_pt
701.1Sjkunz
711.2Smatt	/* Map sections to the page table. */
721.1Sjkunz	ldr	mit_p, =mmu_init_table
731.1Sjkunz	ldmia	mit_p!, {va, pa, n_sec, attr}
741.1Sjkunz
751.1Sjkunz	/*
761.1Sjkunz	 * Calculate PTE addresses for a MVA's.
771.1Sjkunz	 *
781.1Sjkunz	 * Bits[31:14] of the Translation Table Base register are concatenated
791.1Sjkunz	 * with bits[31:20] of the modified virtual address and two zero bits
801.1Sjkunz	 * to produce a physical address of the page table entry for a MVA:
811.1Sjkunz	 *
821.1Sjkunz	 * PTE = (TTBR & 0xffffc000) | ((MVA & 0xfff00000)>>18)
831.1Sjkunz	 */
841.1Sjkunz3:	ldr	tmp, =0xffffc000
851.1Sjkunz	and	pte_p, l1pt_p, tmp
861.1Sjkunz	ldr	tmp, =0xfff00000
871.1Sjkunz	and	va, va, tmp
881.1Sjkunz	mov	va, va, LSR #18
891.1Sjkunz	orr	pte_p, pte_p, va
901.1Sjkunz
911.1Sjkunz2:	orr	sec, pa, attr
921.1Sjkunz	str	sec, [pte_p], #4	/* Store #n_sec sections to the page */
931.1Sjkunz	add	pa, pa, #0x100000	/* table. */
941.1Sjkunz	subs	n_sec, #1
951.1Sjkunz	bne	2b
961.1Sjkunz
971.1Sjkunz	ldmia	mit_p!, {va, pa, n_sec, attr}
981.1Sjkunz	cmp	n_sec, #0
991.1Sjkunz	bne	3b
1001.1Sjkunz
1011.1Sjkunz	/*
1021.1Sjkunz	 * The Translation Table Base Register holds the physical address of
1031.1Sjkunz	 * the page table.
1041.1Sjkunz	 */
1051.1Sjkunz	mcr	p15, 0, l1pt_p, c2, c0, 0
1061.1Sjkunz
1071.1Sjkunz	.unreq	l1pt_p
1081.1Sjkunz	.unreq	mit_p
1091.1Sjkunz	.unreq	va
1101.1Sjkunz	.unreq	pa
1111.1Sjkunz	.unreq	n_sec
1121.1Sjkunz	.unreq	attr
1131.1Sjkunz	.unreq	pte_p
1141.1Sjkunz	.unreq	sec
1151.1Sjkunz	.unreq	tmp
1161.1Sjkunz	.unreq	tmp2
1171.1Sjkunz
1181.1Sjkunz	/*
1191.1Sjkunz	 * Sections are in domain 0 and we set D0 access control to client
1201.1Sjkunz	 * mode, which means AP bits are checked. Since we are running
1211.1Sjkunz	 * privileged mode and APs are kernel read/write, access is granted.
1221.1Sjkunz	 */
1231.1Sjkunz	mov	r0, #DOMAIN_CLIENT<<(PMAP_DOMAIN_KERNEL*2)
1241.1Sjkunz	mcr	p15, 0, r0, c3, c0, 0
1251.1Sjkunz
1261.1Sjkunz	/*
1271.1Sjkunz	 * Enable the MMU.
1281.1Sjkunz	 */
1291.1Sjkunz	mrc	p15, 0, r0, c1, c0, 0
1301.1Sjkunz	ldr	r1, =(CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE \
1311.1Sjkunz			| CPU_CONTROL_AFLT_ENABLE | CPU_CONTROL_MMU_ENABLE)
1321.1Sjkunz	orr	r0, r0, r1
1331.1Sjkunz	mcr	p15, 0, r0, c1, c0, 0
1341.1Sjkunz	nop	/* Fetch flat. */
1351.1Sjkunz	nop	/* Fetch flat. */
1361.1Sjkunz
1371.1Sjkunz	/*
1381.2Smatt	 * Now MMU is on and instruction fetches are translated.
1391.2Smatt	 */
1401.2Smatt
1411.2Smatt	/*
1421.1Sjkunz	 * Jump to start in locore.S. start sets the sp point to DRAM, zeroes
1431.1Sjkunz	 * the .bss and calls initarm. start never returns.
1441.1Sjkunz	 */
1451.1Sjkunz	ldr	pc, =start
1461.2Smatt1:	b	1b
1471.1Sjkunz
1481.1Sjkunz	/* NOTREACHED */
1491.1Sjkunz
1501.1Sjkunz/*
1511.1Sjkunz * Initial first level translation table on a 16kB boundary located at the
1521.1Sjkunz * end of the DRAM.
1531.1Sjkunz *
1541.1Sjkunz * The translation table has 4096 32-bit section entries, each describing 1MB of
1551.1Sjkunz * virtual memory which means 4GB of virtual memory to be addressed.
1561.1Sjkunz */
1571.2Smatt.Ll1_pt:
1581.1Sjkunz	.word (DRAM_BASE + MEMSIZE * 1024 * 1024 - L1_TABLE_SIZE)
1591.1Sjkunz
1601.1Sjkunz#define MMU_INIT(va,pa,n_sec,attr)					\
1611.1Sjkunz	.word va;							\
1621.1Sjkunz	.word pa;							\
1631.1Sjkunz	.word n_sec;							\
1641.1Sjkunz	.word attr;
1651.1Sjkunz
1661.1Sjkunzmmu_init_table:
1671.1Sjkunz	/* On-chip RAM */
1681.1Sjkunz	MMU_INIT(0x00000000, 0x00000000,
1691.1Sjkunz		1,
1701.1Sjkunz		L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_PROTO)
1711.1Sjkunz
1721.1Sjkunz	/* On-chip ROM (Vectors) */
1731.1Sjkunz	MMU_INIT(0xFFFF0000, 0xFFFF0000,
1741.1Sjkunz		1,
1751.1Sjkunz		L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_PROTO)
1761.1Sjkunz
1771.1Sjkunz	/* DRAM */
1781.1Sjkunz	MMU_INIT(KERNEL_BASE_virt, KERNEL_BASE_phys,
1791.1Sjkunz		MEMSIZE,
1801.1Sjkunz		L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_C |\
1811.1Sjkunz			L1_S_B | L1_S_PROTO)
1821.1Sjkunz
1831.2Smatt	/* VA == PA mapping for instruction fetches just after MMU_ENABLE. */
1841.2Smatt	MMU_INIT(KERNEL_BASE_phys, KERNEL_BASE_phys,
1851.2Smatt		1,
1861.2Smatt		L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_C |\
1871.2Smatt			L1_S_B | L1_S_PROTO)
1881.2Smatt
1891.1Sjkunz	/* Peripherals */
1901.1Sjkunz	MMU_INIT(APBH_BASE, APBH_BASE,
1911.1Sjkunz		1,
1921.1Sjkunz		L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_PROTO)
1931.1Sjkunz
1941.1Sjkunz	MMU_INIT(0, 0, 0, 0)
1951.2Smatt
1961.2Smatt#ifdef DEBUG
1971.2Smatt/*
1981.2Smatt * Write character in r0 register to Debug UART.
1991.2Smatt */
2001.2Smatt.global	_C_LABEL(dbputc)
2011.2Smatt_C_LABEL(dbputc):
2021.2Smatt	stmfd	sp!, {r0, r1, r2, lr}
2031.2Smatt
2041.2Smatt        /* Wait until transmit FIFO has space for the new character. */
2051.2Smatt	ldr	r1, =(HW_UARTDBG_BASE + HW_UARTDBGFR)
2061.2Smatt1:	ldr	r2, [r1]
2071.2Smatt	ands	r2, r2, #0x20	/* HW_UARTDBGFR_TXFF */
2081.2Smatt	bne	1b
2091.2Smatt
2101.2Smatt	ldr	r1, =(HW_UARTDBG_BASE + HW_UARTDBGDR)
2111.2Smatt	strb	r0, [r1]
2121.2Smatt
2131.2Smatt	ldmfd	sp!, {r0, r1, r2, pc}
2141.2Smatt#endif
215