1/* $Id: imx23_olinuxino_start.S,v 1.3 2015/01/10 12:11:39 jmcneill Exp $ */
2
3/*
4 * Copyright (c) 2012 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Petri Laakso.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "opt_imx.h"
33
34#include <machine/asm.h>
35#include <machine/pmap.h>
36#include <arm/armreg.h>
37#include <arm/imx/imx23var.h>
38#ifdef DEBUG
39#include <arm/imx/imx23_uartdbgreg.h>
40#endif
41
42.section .start,"ax",%progbits
43
44.global   _C_LABEL(olinuxino_start)
45_C_LABEL(olinuxino_start):
46          /*
47           * Set up the first level page table. The page table has 4096 section
48           * page table entries which each one maps 1MB of virtual memory.
49           * Section entries are mapped from mmu_init_table to the page table.
50           */
51          l1pt_p    .req r0
52          mit_p     .req r1
53          va        .req r2
54          pa        .req r3
55          n_sec     .req r4
56          attr      .req r5
57          pte_p     .req r6
58          sec       .req r7
59          tmp       .req r8
60          tmp2      .req r9
61
62          ldr       l1pt_p, .Ll1_pt
63
64          /* Zero the page table. */
65          mov       tmp, #0
66          add       tmp2, l1pt_p, #L1_TABLE_SIZE
671:        str       tmp, [l1pt_p], #4
68          cmp       l1pt_p, tmp2
69          blt       1b
70
71          ldr       l1pt_p, .Ll1_pt
72
73          /* Map sections to the page table. */
74          ldr       mit_p, =mmu_init_table
75          ldmia     mit_p!, {va, pa, n_sec, attr}
76
77          /*
78           * Calculate PTE addresses for a MVA's.
79           *
80           * Bits[31:14] of the Translation Table Base register are concatenated
81           * with bits[31:20] of the modified virtual address and two zero bits
82           * to produce a physical address of the page table entry for a MVA:
83           *
84           * PTE = (TTBR & 0xffffc000) | ((MVA & 0xfff00000)>>18)
85           */
863:        ldr       tmp, =0xffffc000
87          and       pte_p, l1pt_p, tmp
88          ldr       tmp, =0xfff00000
89          and       va, va, tmp
90          mov       va, va, LSR #18
91          orr       pte_p, pte_p, va
92
932:        orr       sec, pa, attr
94          str       sec, [pte_p], #4    /* Store #n_sec sections to the page */
95          add       pa, pa, #0x100000   /* table. */
96          subs      n_sec, #1
97          bne       2b
98
99          ldmia     mit_p!, {va, pa, n_sec, attr}
100          cmp       n_sec, #0
101          bne       3b
102
103          /*
104           * The Translation Table Base Register holds the physical address of
105           * the page table.
106           */
107          mcr       p15, 0, l1pt_p, c2, c0, 0
108
109          .unreq    l1pt_p
110          .unreq    mit_p
111          .unreq    va
112          .unreq    pa
113          .unreq    n_sec
114          .unreq    attr
115          .unreq    pte_p
116          .unreq    sec
117          .unreq    tmp
118          .unreq    tmp2
119
120          /*
121           * Sections are in domain 0 and we set D0 access control to client
122           * mode, which means AP bits are checked. Since we are running
123           * privileged mode and APs are kernel read/write, access is granted.
124           */
125          mov       r0, #DOMAIN_CLIENT<<(PMAP_DOMAIN_KERNEL*2)
126          mcr       p15, 0, r0, c3, c0, 0
127
128          /*
129           * Enable the MMU.
130           */
131          mrc       p15, 0, r0, c1, c0, 0
132          ldr       r1, =(CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE \
133                              | CPU_CONTROL_AFLT_ENABLE | CPU_CONTROL_MMU_ENABLE)
134          orr       r0, r0, r1
135          mcr       p15, 0, r0, c1, c0, 0
136          nop       /* Fetch flat. */
137          nop       /* Fetch flat. */
138
139          /*
140           * Now MMU is on and instruction fetches are translated.
141           */
142
143          /*
144           * Jump to start in locore.S. start sets the sp point to DRAM, zeroes
145           * the .bss and calls initarm. start never returns.
146           */
147          ldr       pc, =start
1481:        b         1b
149
150          /* NOTREACHED */
151
152/*
153 * Initial first level translation table on a 16kB boundary located at the
154 * end of the DRAM.
155 *
156 * The translation table has 4096 32-bit section entries, each describing 1MB of
157 * virtual memory which means 4GB of virtual memory to be addressed.
158 */
159.Ll1_pt:
160          .word (DRAM_BASE + MEMSIZE * 1024 * 1024 - L1_TABLE_SIZE)
161
162#define MMU_INIT(va,pa,n_sec,attr)                                              \
163          .word va;                                                             \
164          .word pa;                                                             \
165          .word n_sec;                                                                    \
166          .word attr;
167
168mmu_init_table:
169          /* On-chip RAM */
170          MMU_INIT(0x00000000, 0x00000000,
171                    1,
172                    L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_PROTO)
173
174          /* On-chip ROM (Vectors) */
175          MMU_INIT(0xFFFF0000, 0xFFFF0000,
176                    1,
177                    L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_PROTO)
178
179          /* DRAM */
180          MMU_INIT(KERNEL_BASE_virt, KERNEL_BASE_phys,
181                    MEMSIZE,
182                    L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_C |\
183                              L1_S_B | L1_S_PROTO)
184
185          /* VA == PA mapping for instruction fetches just after MMU_ENABLE. */
186          MMU_INIT(KERNEL_BASE_phys, KERNEL_BASE_phys,
187                    1,
188                    L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_C |\
189                              L1_S_B | L1_S_PROTO)
190
191          /* Peripherals */
192          MMU_INIT(APBH_BASE, APBH_BASE,
193                    1,
194                    L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_PROTO)
195
196          MMU_INIT(0, 0, 0, 0)
197
198#ifdef DEBUG
199/*
200 * Write character in r0 register to Debug UART.
201 */
202.global   _C_LABEL(dbputc)
203_C_LABEL(dbputc):
204          stmfd     sp!, {r0, r1, r2, lr}
205
206        /* Wait until transmit FIFO has space for the new character. */
207          ldr       r1, =(HW_UARTDBG_BASE + HW_UARTDBGFR)
2081:        ldr       r2, [r1]
209          ands      r2, r2, #0x20       /* HW_UARTDBGFR_TXFF */
210          bne       1b
211
212          ldr       r1, =(HW_UARTDBG_BASE + HW_UARTDBGDR)
213          strb      r0, [r1]
214
215          ldmfd     sp!, {r0, r1, r2, pc}
216#endif
217