Commit | Line | Data |
---|---|---|
c121c506 VG |
1 | /* |
2 | * ARC CPU startup Code | |
3 | * | |
4 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 as | |
8 | * published by the Free Software Foundation. | |
9 | * | |
10 | * Vineetg: Dec 2007 | |
11 | * -Check if we are running on Simulator or on real hardware | |
12 | * to skip certain things during boot on simulator | |
13 | */ | |
14 | ||
ef680cdc | 15 | #include <linux/linkage.h> |
c121c506 VG |
16 | #include <asm/asm-offsets.h> |
17 | #include <asm/entry.h> | |
c121c506 | 18 | #include <asm/arcregs.h> |
ef680cdc VG |
19 | #include <asm/cache.h> |
20 | ||
21 | .macro CPU_EARLY_SETUP | |
22 | ||
23 | ; Setting up Vectror Table (in case exception happens in early boot | |
24 | sr @_int_vec_base_lds, [AUX_INTR_VEC_BASE] | |
25 | ||
26 | ; Disable I-cache/D-cache if kernel so configured | |
27 | lr r5, [ARC_REG_IC_BCR] | |
28 | breq r5, 0, 1f ; I$ doesn't exist | |
29 | lr r5, [ARC_REG_IC_CTRL] | |
30 | #ifdef CONFIG_ARC_HAS_ICACHE | |
31 | bclr r5, r5, 0 ; 0 - Enable, 1 is Disable | |
32 | #else | |
33 | bset r5, r5, 0 ; I$ exists, but is not used | |
34 | #endif | |
35 | sr r5, [ARC_REG_IC_CTRL] | |
36 | ||
37 | 1: | |
38 | lr r5, [ARC_REG_DC_BCR] | |
39 | breq r5, 0, 1f ; D$ doesn't exist | |
40 | lr r5, [ARC_REG_DC_CTRL] | |
41 | bclr r5, r5, 6 ; Invalidate (discard w/o wback) | |
42 | #ifdef CONFIG_ARC_HAS_DCACHE | |
43 | bclr r5, r5, 0 ; Enable (+Inv) | |
44 | #else | |
45 | bset r5, r5, 0 ; Disable (+Inv) | |
46 | #endif | |
47 | sr r5, [ARC_REG_DC_CTRL] | |
48 | ||
49 | 1: | |
50 | .endm | |
c121c506 VG |
51 | |
52 | .cpu A7 | |
53 | ||
54 | .section .init.text, "ax",@progbits | |
55 | .type stext, @function | |
56 | .globl stext | |
57 | stext: | |
58 | ;------------------------------------------------------------------- | |
c3441edd | 59 | ; Don't clobber r0-r2 yet. It might have bootloader provided info |
c121c506 VG |
60 | ;------------------------------------------------------------------- |
61 | ||
ef680cdc | 62 | CPU_EARLY_SETUP |
05b016ec | 63 | |
41195d23 | 64 | #ifdef CONFIG_SMP |
c3441edd | 65 | ; Ensure Boot (Master) proceeds. Others wait in platform dependent way |
41195d23 VG |
66 | ; IDENTITY Reg [ 3 2 1 0 ] |
67 | ; (cpu-id) ^^^ => Zero for UP ARC700 | |
68 | ; => #Core-ID if SMP (Master 0) | |
c3567f8a NC |
69 | ; Note that non-boot CPUs might not land here if halt-on-reset and |
70 | ; instead breath life from @first_lines_of_secondary, but we still | |
71 | ; need to make sure only boot cpu takes this path. | |
41195d23 VG |
72 | GET_CPU_ID r5 |
73 | cmp r5, 0 | |
c3441edd VG |
74 | mov.ne r0, r5 |
75 | jne arc_platform_smp_wait_to_boot | |
41195d23 | 76 | #endif |
c121c506 VG |
77 | ; Clear BSS before updating any globals |
78 | ; XXX: use ZOL here | |
79 | mov r5, __bss_start | |
80 | mov r6, __bss_stop | |
81 | 1: | |
82 | st.ab 0, [r5,4] | |
83 | brlt r5, r6, 1b | |
84 | ||
59ed9413 VG |
85 | ; Uboot - kernel ABI |
86 | ; r0 = [0] No uboot interaction, [1] cmdline in r2, [2] DTB in r2 | |
87 | ; r1 = magic number (board identity, unused as of now | |
88 | ; r2 = pointer to uboot provided cmdline or external DTB in mem | |
89 | ; These are handled later in setup_arch() | |
90 | st r0, [@uboot_tag] | |
91 | st r2, [@uboot_arg] | |
c121c506 VG |
92 | |
93 | ; Identify if running on ISS vs Silicon | |
94 | ; IDENTITY Reg [ 3 2 1 0 ] | |
95 | ; (chip-id) ^^^^^ ==> 0xffff for ISS | |
96 | lr r0, [identity] | |
97 | lsr r3, r0, 16 | |
98 | cmp r3, 0xffff | |
99 | mov.z r4, 0 | |
100 | mov.nz r4, 1 | |
101 | st r4, [@running_on_hw] | |
102 | ||
103 | ; setup "current" tsk and optionally cache it in dedicated r25 | |
104 | mov r9, @init_task | |
105 | SET_CURR_TASK_ON_CPU r9, r0 ; r9 = tsk, r0 = scratch | |
106 | ||
107 | ; setup stack (fp, sp) | |
108 | mov fp, 0 | |
109 | ||
110 | ; tsk->thread_info is really a PAGE, whose bottom hoists stack | |
111 | GET_TSK_STACK_BASE r9, sp ; r9 = tsk, sp = stack base(output) | |
112 | ||
113 | j start_kernel ; "C" entry point | |
41195d23 VG |
114 | |
115 | #ifdef CONFIG_SMP | |
116 | ;---------------------------------------------------------------- | |
117 | ; First lines of code run by secondary before jumping to 'C' | |
118 | ;---------------------------------------------------------------- | |
8f5d221b | 119 | .section .text, "ax",@progbits |
41195d23 VG |
120 | .type first_lines_of_secondary, @function |
121 | .globl first_lines_of_secondary | |
122 | ||
123 | first_lines_of_secondary: | |
124 | ||
ef680cdc | 125 | CPU_EARLY_SETUP |
c3567f8a | 126 | |
41195d23 VG |
127 | ; setup per-cpu idle task as "current" on this CPU |
128 | ld r0, [@secondary_idle_tsk] | |
129 | SET_CURR_TASK_ON_CPU r0, r1 | |
130 | ||
131 | ; setup stack (fp, sp) | |
132 | mov fp, 0 | |
133 | ||
134 | ; set it's stack base to tsk->thread_info bottom | |
135 | GET_TSK_STACK_BASE r0, sp | |
136 | ||
137 | j start_kernel_secondary | |
138 | ||
139 | #endif |