aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel/head_32.S
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2010-05-28 23:09:12 -0400
committerChris Metcalf <cmetcalf@tilera.com>2010-06-04 17:11:18 -0400
commit867e359b97c970a60626d5d76bbe2a8fadbf38fb (patch)
treec5ccbb7f5172e8555977119608ecb1eee3cc37e3 /arch/tile/kernel/head_32.S
parent5360bd776f73d0a7da571d72a09a03f237e99900 (diff)
arch/tile: core support for Tilera 32-bit chips.
This change is the core kernel support for TILEPro and TILE64 chips. No driver support (except the console driver) is included yet. This includes the relevant Linux headers in asm/; the low-level low-level "Tile architecture" headers in arch/, which are shared with the hypervisor, etc., and are build-system agnostic; and the relevant hypervisor headers in hv/. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Acked-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Reviewed-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/tile/kernel/head_32.S')
-rw-r--r--arch/tile/kernel/head_32.S180
1 files changed, 180 insertions, 0 deletions
diff --git a/arch/tile/kernel/head_32.S b/arch/tile/kernel/head_32.S
new file mode 100644
index 000000000000..2b4f6c091701
--- /dev/null
+++ b/arch/tile/kernel/head_32.S
@@ -0,0 +1,180 @@
1/*
2 * Copyright 2010 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 *
14 * TILE startup code.
15 */
16
17#include <linux/linkage.h>
18#include <linux/init.h>
19#include <asm/page.h>
20#include <asm/pgtable.h>
21#include <asm/thread_info.h>
22#include <asm/processor.h>
23#include <asm/asm-offsets.h>
24#include <hv/hypervisor.h>
25#include <arch/chip.h>
26
27/*
28 * This module contains the entry code for kernel images. It performs the
29 * minimal setup needed to call the generic C routines.
30 */
31
32 __HEAD
33ENTRY(_start)
34 /* Notify the hypervisor of what version of the API we want */
35 {
36 movei r1, TILE_CHIP
37 movei r2, TILE_CHIP_REV
38 }
39 {
40 moveli r0, _HV_VERSION
41 jal hv_init
42 }
43 /* Get a reasonable default ASID in r0 */
44 {
45 move r0, zero
46 jal hv_inquire_asid
47 }
48 /* Install the default page table */
49 {
50 moveli r6, lo16(swapper_pgprot - PAGE_OFFSET)
51 move r4, r0 /* use starting ASID of range for this page table */
52 }
53 {
54 moveli r0, lo16(swapper_pg_dir - PAGE_OFFSET)
55 auli r6, r6, ha16(swapper_pgprot - PAGE_OFFSET)
56 }
57 {
58 lw r2, r6
59 addi r6, r6, 4
60 }
61 {
62 lw r3, r6
63 auli r0, r0, ha16(swapper_pg_dir - PAGE_OFFSET)
64 }
65 {
66 inv r6
67 move r1, zero /* high 32 bits of CPA is zero */
68 }
69 {
70 moveli lr, lo16(1f)
71 move r5, zero
72 }
73 {
74 auli lr, lr, ha16(1f)
75 j hv_install_context
76 }
771:
78
79 /* Get our processor number and save it away in SAVE_1_0. */
80 jal hv_inquire_topology
81 mulll_uu r4, r1, r2 /* r1 == y, r2 == width */
82 add r4, r4, r0 /* r0 == x, so r4 == cpu == y*width + x */
83
84#ifdef CONFIG_SMP
85 /*
86 * Load up our per-cpu offset. When the first (master) tile
87 * boots, this value is still zero, so we will load boot_pc
88 * with start_kernel, and boot_sp with init_stack + THREAD_SIZE.
89 * The master tile initializes the per-cpu offset array, so that
90 * when subsequent (secondary) tiles boot, they will instead load
91 * from their per-cpu versions of boot_sp and boot_pc.
92 */
93 moveli r5, lo16(__per_cpu_offset)
94 auli r5, r5, ha16(__per_cpu_offset)
95 s2a r5, r4, r5
96 lw r5, r5
97 bnz r5, 1f
98
99 /*
100 * Save the width and height to the smp_topology variable
101 * for later use.
102 */
103 moveli r0, lo16(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
104 auli r0, r0, ha16(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
105 {
106 sw r0, r2
107 addi r0, r0, (HV_TOPOLOGY_HEIGHT_OFFSET - HV_TOPOLOGY_WIDTH_OFFSET)
108 }
109 sw r0, r3
1101:
111#else
112 move r5, zero
113#endif
114
115 /* Load and go with the correct pc and sp. */
116 {
117 addli r1, r5, lo16(boot_sp)
118 addli r0, r5, lo16(boot_pc)
119 }
120 {
121 auli r1, r1, ha16(boot_sp)
122 auli r0, r0, ha16(boot_pc)
123 }
124 lw r0, r0
125 lw sp, r1
126 or r4, sp, r4
127 mtspr SYSTEM_SAVE_1_0, r4 /* save ksp0 + cpu */
128 addi sp, sp, -STACK_TOP_DELTA
129 {
130 move lr, zero /* stop backtraces in the called function */
131 jr r0
132 }
133 ENDPROC(_start)
134
135.section ".bss.page_aligned","w"
136 .align PAGE_SIZE
137ENTRY(empty_zero_page)
138 .fill PAGE_SIZE,1,0
139 END(empty_zero_page)
140
141 .macro PTE va, cpa, bits1, no_org=0
142 .ifeq \no_org
143 .org swapper_pg_dir + HV_L1_INDEX(\va) * HV_PTE_SIZE
144 .endif
145 .word HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED | \
146 (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE)
147 .word (\bits1) | (HV_CPA_TO_PFN(\cpa) << HV_PTE_INDEX_PFN)
148 .endm
149
150.section ".data.page_aligned","wa"
151 .align PAGE_SIZE
152ENTRY(swapper_pg_dir)
153 /*
154 * All data pages from PAGE_OFFSET to MEM_USER_INTRPT are mapped as
155 * VA = PA + PAGE_OFFSET. We remap things with more precise access
156 * permissions and more respect for size of RAM later.
157 */
158 .set addr, 0
159 .rept (MEM_USER_INTRPT - PAGE_OFFSET) >> PGDIR_SHIFT
160 PTE addr + PAGE_OFFSET, addr, HV_PTE_READABLE | HV_PTE_WRITABLE
161 .set addr, addr + PGDIR_SIZE
162 .endr
163
164 /* The true text VAs are mapped as VA = PA + MEM_SV_INTRPT */
165 PTE MEM_SV_INTRPT, 0, HV_PTE_READABLE | HV_PTE_EXECUTABLE
166 .org swapper_pg_dir + HV_L1_SIZE
167 END(swapper_pg_dir)
168
169 /*
170 * Isolate swapper_pgprot to its own cache line, since each cpu
171 * starting up will read it using VA-is-PA and local homing.
172 * This would otherwise likely conflict with other data on the cache
173 * line, once we have set its permanent home in the page tables.
174 */
175 __INITDATA
176 .align CHIP_L2_LINE_SIZE()
177ENTRY(swapper_pgprot)
178 PTE 0, 0, HV_PTE_READABLE | HV_PTE_WRITABLE, 1
179 .align CHIP_L2_LINE_SIZE()
180 END(swapper_pgprot)