xref: /netbsd-src/sys/arch/evbarm/mpcsa/mpcsa_start.S (revision 497ddd31b9b804e6b142bfec8ba4b02379916202)
1c62a0ac4Smatt/*
2c62a0ac4Smatt * mpcsa_start.S
3c62a0ac4Smatt * Copyright (c) 2007, S. Kantoluoto <sami.kantoluoto@iki.fi>
4c62a0ac4Smatt * All rights reserved.
5c62a0ac4Smatt *
6c62a0ac4Smatt * Based on vx115_vep_start.S
7c62a0ac4Smatt * Copyright (c) 2007, J. Sevy <jsevy@cs.drexel.edu>
8c62a0ac4Smatt *
9c62a0ac4Smatt * Based on g42xxeb_start.S
10c62a0ac4Smatt * Copyright (c) 2002, 2003  Genetec Corporation.  All rights reserved.
11c62a0ac4Smatt * Written by Hiroyuki Bessho for Genetec Corporation.
12c62a0ac4Smatt *
13c62a0ac4Smatt * Redistribution and use in source and binary forms, with or without
14c62a0ac4Smatt * modification, are permitted provided that the following conditions
15c62a0ac4Smatt * are met:
16c62a0ac4Smatt * 1. Redistributions of source code must retain the above copyright
17c62a0ac4Smatt *    notice, this list of conditions and the following disclaimer.
18c62a0ac4Smatt * 2. Redistributions in binary form must reproduce the above copyright
19c62a0ac4Smatt *    notice, this list of conditions and the following disclaimer in the
20c62a0ac4Smatt *    documentation and/or other materials provided with the distribution.
21c62a0ac4Smatt * 3. The name of Genetec Corporation may not be used to endorse or
22c62a0ac4Smatt *    promote products derived from this software without specific prior
23c62a0ac4Smatt *    written permission.
24c62a0ac4Smatt *
25c62a0ac4Smatt * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
26c62a0ac4Smatt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27c62a0ac4Smatt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28c62a0ac4Smatt * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
29c62a0ac4Smatt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30c62a0ac4Smatt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31c62a0ac4Smatt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32c62a0ac4Smatt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33c62a0ac4Smatt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34c62a0ac4Smatt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35c62a0ac4Smatt * POSSIBILITY OF SUCH DAMAGE.
36c62a0ac4Smatt */
37c62a0ac4Smatt
38c62a0ac4Smatt#include <machine/asm.h>
39c62a0ac4Smatt#include <arm/armreg.h>
40*497ddd31Smatt#include "assym.h"
41*497ddd31Smatt
42*497ddd31SmattRCSID("$NetBSD: mpcsa_start.S,v 1.3 2011/01/31 06:28:04 matt Exp $")
43c62a0ac4Smatt
44c62a0ac4Smatt#ifndef	FLASH_START
45c62a0ac4Smatt#define	FLASH_START	0x10020000
46c62a0ac4Smatt#endif
47c62a0ac4Smatt
48c62a0ac4Smatt#ifndef SDRAM_START
49c62a0ac4Smatt#define SDRAM_START    0x20000000
50c62a0ac4Smatt#endif
51c62a0ac4Smatt
52c62a0ac4Smatt#define	MODBASE	       0x20200000
53c62a0ac4Smatt
54c62a0ac4Smatt/*
55c62a0ac4Smatt * CPWAIT -- Canonical method to wait for CP15 update.
56c62a0ac4Smatt * NOTE: Clobbers the specified temp reg.
57c62a0ac4Smatt * copied from arm/arm/cpufunc_asm_xscale.S
58c62a0ac4Smatt * XXX: better be in a common header file.
59c62a0ac4Smatt */
60c62a0ac4Smatt#define    CPWAIT_BRANCH    \
61c62a0ac4Smatt    sub pc, pc, #4
62c62a0ac4Smatt
63c62a0ac4Smatt#define    CPWAIT(tmp)                             				 \
64c62a0ac4Smatt    mrc p15, 0, tmp, c2, c0, 0  /* arbitrary read of CP15 */    ;\
65c62a0ac4Smatt    mov tmp, tmp        		/* wait for it to complete */   ;\
66c62a0ac4Smatt    CPWAIT_BRANCH            	/* branch to next insn */
67c62a0ac4Smatt
68c62a0ac4Smatt/*
69c62a0ac4Smatt * Kernel start routine for MPCSA board.
70c62a0ac4Smatt * This code is executed from Flash when the bootloader jumps to it.
71c62a0ac4Smatt */
72c62a0ac4Smatt    .text
73c62a0ac4Smatt
74c62a0ac4Smatt    .global _C_LABEL(mpcsa_start)
75c62a0ac4Smatt_C_LABEL(mpcsa_start):
76c62a0ac4Smatt
77c62a0ac4Smatt    /* make sure we're in supervisor mode */
78c62a0ac4Smatt    mov	   r0,sp
79c62a0ac4Smatt    msr    CPSR_c,#I32_bit | F32_bit | PSR_SVC32_MODE
80c62a0ac4Smatt    mov	   sp,r0
81c62a0ac4Smatt
82c62a0ac4Smatt    /* move code to RAM */
83c62a0ac4Smatt    ldr    r1, Lcopy_size
84c62a0ac4Smatt    adr    r0, _C_LABEL(mpcsa_start)
85c62a0ac4Smatt    add    r1, r1, #3
86c62a0ac4Smatt    mov    r1, r1, LSR #2         /* get size of code in words */
87c62a0ac4Smatt    mov    r2, #SDRAM_START
88c62a0ac4Smatt    add    r2, r2, #0x200000    /* code placed 2MB above kernel base */
89c62a0ac4Smatt    mov    r4, r2
90c62a0ac4Smatt
91c62a0ac4Smatt    /* copy kernel to RAM */
92c62a0ac4Smatt5:  ldr    r3, [r0], #4
93c62a0ac4Smatt    subs   r1, r1, #1
94c62a0ac4Smatt    str    r3, [r2], #4
95c62a0ac4Smatt    bhi    5b
96c62a0ac4Smatt
97c62a0ac4Smatt    /* jump to RAM */
98c62a0ac4Smatt    ldr    r0, Lstart_off
99c62a0ac4Smatt    add    pc, r4, r0
100c62a0ac4Smatt
101c62a0ac4Smatt
102c62a0ac4SmattLcopy_size:    .word _edata-_C_LABEL(mpcsa_start)
103c62a0ac4SmattLstart_off:    .word mpcsa_start_ram-_C_LABEL(mpcsa_start)
104c62a0ac4Smatt
105c62a0ac4Smattmpcsa_start_ram:
106c62a0ac4Smatt    /*
107c62a0ac4Smatt     *  Kernel is loaded in SDRAM (0x20200000), and is expected to run
108c62a0ac4Smatt     *  in VA 0xc0200000.
109c62a0ac4Smatt     */
110c62a0ac4Smatt
111c62a0ac4Smatt    /* build page table from scratch */
112c62a0ac4Smatt    ldr    r0, Lstartup_pagetable
113c62a0ac4Smatt    adr    r4, mmu_init_table
114c62a0ac4Smatt    b      3f
115c62a0ac4Smatt
116c62a0ac4Smatt2:
117c62a0ac4Smatt    str    r3, [r0, r2]
118c62a0ac4Smatt    add    r2, r2, #4
119c62a0ac4Smatt    add    r3, r3, #(L1_S_SIZE)
120c62a0ac4Smatt    adds   r1, r1, #-1
121c62a0ac4Smatt    bhi    2b
122c62a0ac4Smatt3:
123c62a0ac4Smatt    ldmia  r4!, {r1,r2,r3}   /* # of sections, PA|attr, VA */
124c62a0ac4Smatt    cmp    r1, #0
125c62a0ac4Smatt    bne    2b
126c62a0ac4Smatt
127c62a0ac4Smatt
128c62a0ac4Smatt    mcr    p15, 0, r0, c2, c0, 0    /* Set TTB */
129c62a0ac4Smatt    mcr    p15, 0, r0, c8, c7, 0    /* Flush TLB */
130c62a0ac4Smatt
131c62a0ac4Smatt    /* Set the Domain Access register.  Very important! */
132c62a0ac4Smatt    mov    r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
133c62a0ac4Smatt    mcr    p15, 0, r0, c3, c0, 0
134c62a0ac4Smatt
135c62a0ac4Smatt    /* Enable MMU */
136c62a0ac4Smatt    mrc    p15, 0, r0, c1, c0, 0
137c62a0ac4Smatt    orr    r0, r0, #CPU_CONTROL_MMU_ENABLE
138c62a0ac4Smatt    mcr    p15, 0, r0, c1, c0, 0
139c62a0ac4Smatt    CPWAIT(r0)
140c62a0ac4Smatt
141c62a0ac4Smatt    /* Jump to kernel code in TRUE VA */
142c62a0ac4Smatt    adr    r0, Lstart
143c62a0ac4Smatt    ldr    pc, [r0]
144c62a0ac4Smatt
145c62a0ac4SmattLstart:
146c62a0ac4Smatt    .word    start
147c62a0ac4Smatt
148c62a0ac4Smatt
149c62a0ac4Smatt#define MMU_INIT(va,pa,n_sec,attr)  \
150c62a0ac4Smatt    .word    n_sec                 ;\
151c62a0ac4Smatt    .word    4*((va)>>L1_S_SHIFT)  ;\
152c62a0ac4Smatt    .word    (pa) | (attr)
153c62a0ac4Smatt
154c62a0ac4Smatt#define STARTUP_PAGETABLE_ADDR  0x20100000 + 0x4000
155c62a0ac4Smatt
156c62a0ac4SmattLstartup_pagetable:
157c62a0ac4Smatt	.word STARTUP_PAGETABLE_ADDR
158c62a0ac4Smatt
159c62a0ac4Smattmmu_init_table:
160c62a0ac4Smatt    /* fill all table VA==PA */
161*497ddd31Smatt    MMU_INIT(0x00000000, 0x00000000, 1<<(32-L1_S_SHIFT), L1_TYPE_S|L1_S_AP_KRW)
162c62a0ac4Smatt    /* map in peripheral space */
163*497ddd31Smatt    MMU_INIT(0xfff00000, 0xfff00000, 1, L1_TYPE_S|L1_S_AP_KRW)
164c62a0ac4Smatt    /* map SDRAM VA==PA, WT cacheable */
165*497ddd31Smatt    MMU_INIT(0x20100000, 0x20100000, 63, L1_TYPE_S|L1_S_C|L1_S_AP_KRW)
166c62a0ac4Smatt    /* map VA 0xc0000000..0xc0efffff to PA 0x20100000..0x23ffffff */
167*497ddd31Smatt    MMU_INIT(0xc0000000, 0x20000000, 63, L1_TYPE_S|L1_S_C|L1_S_AP_KRW)
168c62a0ac4Smatt    .word 0    /* end of table */
169c62a0ac4Smatt
170c62a0ac4Smatt	.align	7
171c62a0ac4Smattjme_module_header:
172c62a0ac4Smatt	.word	0xe990510e		/* magic number			*/
173c62a0ac4Smatt	.string	"NetBSD/mpcsa\0\0\0"	/* module name			*/
174c62a0ac4Smatt	.short	0			/* build flags			*/
175c62a0ac4Smatt	.short	0			/* flags			*/
176c62a0ac4Smatt	.word	0			/* version			*/
177c62a0ac4Smatt	.word	0			/* compile / link timestamp	*/
178c62a0ac4Smatt	.word	MODBASE		/* pointer to init routine	*/
179c62a0ac4Smatt	.word	MODBASE		/* start address		*/
180c62a0ac4Smatt	.word	(_edata-(_C_LABEL(mpcsa_start)))			/* length of module		*/
181c62a0ac4Smatt	.word	(jme_module_header-_C_LABEL(mpcsa_start)+MODBASE)			/* back pointer to module struct*/
182c62a0ac4Smatt	.word	0			/* data pointer (ignored but SBZ)*/
183c62a0ac4Smatt	.word	0			/* data length (ignored but SBZ)*/
184c62a0ac4Smatt	.word	0x20200000		/* alternate address		*/
185c62a0ac4Smatt	.word	0			/* reserved, SBZ		*/
186c62a0ac4Smatt
187c62a0ac4Smattjme_kmodule_header:
188c62a0ac4Smatt	.word	0xe000301e		/* magic number			*/
189c62a0ac4Smatt	.string	"JME kernel\0\0\0\0\0"	/* module name			*/
190c62a0ac4Smatt	.short	0			/* build flags			*/
191c62a0ac4Smatt	.short	0			/* flags			*/
192c62a0ac4Smatt	.word	0			/* version			*/
193c62a0ac4Smatt	.word	0			/* compile / link timestamp	*/
194c62a0ac4Smatt	.word	MODBASE		/* pointer to init routine	*/
195c62a0ac4Smatt	.word	MODBASE		/* start address		*/
196c62a0ac4Smatt	.word	(_edata-(_C_LABEL(mpcsa_start)))			/* length of module		*/
197c62a0ac4Smatt	.word	(jme_kmodule_header-_C_LABEL(mpcsa_start)+MODBASE)	/* back pointer to module struct*/
198c62a0ac4Smatt	.word	0			/* data pointer (ignored but SBZ)*/
199c62a0ac4Smatt	.word	0			/* data length (ignored but SBZ)*/
200c62a0ac4Smatt	.word	0x20200000		/* alternate address		*/
201c62a0ac4Smatt	.word	0			/* reserved, SBZ		*/
202