Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / arch / sparc64 / entry.S
1 /**
2  ** Standalone startup code for Linux PROM emulator.
3  ** Copyright 1999 Pete A. Zaitcev
4  ** This code is licensed under GNU General Public License.
5  **/
6 /*
7  * $Id: head.S,v 1.12 2002/07/23 05:47:09 zaitcev Exp $
8  */
9
10 #define __ASSEMBLY__
11 #include <asm/asi.h>
12 #include "pstate.h"
13 #include "lsu.h"
14 #define NO_QEMU_PROTOS
15 #define NO_OPENBIOS_PROTOS
16 #include "arch/common/fw_cfg.h"
17
18 #define PROM_ADDR 0x1fff0000000
19 #define CFG_ADDR  0x1fe02000510
20 #define HZ        1 * 1000 * 1000
21 #define TICK_INT_DIS 0x8000000000000000
22
23         .globl  entry, _entry
24
25         .section ".text", "ax"
26         .align  8
27         .register %g2, #scratch
28         .register %g3, #scratch
29         .register %g6, #scratch
30         .register %g7, #scratch
31
32 /*
33  * Entry point
34  * We start execution from here.
35  */
36 _entry:
37 entry:
38         ! Set up CPU state
39         wrpr    %g0, PSTATE_PRIV, %pstate
40         wr      %g0, 0, %fprs
41         wrpr    %g0, 0x0, %tl
42
43         ! Extract NWINDOWS from %ver
44         rdpr    %ver, %g1
45         and     %g1, 0xf, %g1
46         dec     %g1
47         wrpr    %g1, 0, %cleanwin
48         wrpr    %g1, 0, %cansave
49         wrpr    %g0, 0, %canrestore
50         wrpr    %g0, 0, %otherwin
51         wrpr    %g0, 0, %wstate
52         ! disable timer now
53         setx    TICK_INT_DIS, %g2, %g1
54         wr      %g1, 0, %tick_cmpr
55
56         ! Disable I/D MMUs and caches
57         stxa    %g0, [%g0] ASI_LSU_CONTROL
58
59         ! Check signature "QEMU"
60         setx    CFG_ADDR, %g2, %g5
61         mov     FW_CFG_SIGNATURE, %g2
62         stha    %g2, [%g5] ASI_PHYS_BYPASS_EC_E_L
63         inc     %g5
64         lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g2
65         cmp     %g2, 'Q'
66         bne     bad_conf
67          nop
68         lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g2
69         cmp     %g2, 'E'
70         bne     bad_conf
71          nop
72         lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g2
73         cmp     %g2, 'M'
74         bne     bad_conf
75          nop
76         lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g2
77         cmp     %g2, 'U'
78         bne     bad_conf
79          nop
80
81         ! Clear ITLB
82         mov     6 << 3, %g1
83         stxa    %g0, [%g1] ASI_IMMU
84         stxa    %g0, [%g1] ASI_DMMU
85         mov     63 << 3, %g1
86 1:      stxa    %g0, [%g1] ASI_ITLB_DATA_ACCESS
87         subcc   %g1, 1 << 3, %g1
88         bpos    1b
89          nop
90
91         ! Clear DTLB
92         mov     63 << 3, %g1
93 1:      stxa    %g0, [%g1] ASI_DTLB_DATA_ACCESS
94         subcc   %g1, 1 << 3, %g1
95         bpos    1b
96          nop
97
98         ! Get memory size from configuration device
99         ! NB: little endian format
100         mov     FW_CFG_RAM_SIZE, %g2
101         dec     %g5
102         stha    %g2, [%g5] ASI_PHYS_BYPASS_EC_E_L
103         inc     %g5
104         lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g4
105
106         lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g3
107         sllx    %g3, 8, %g3
108         or      %g3, %g4, %g4
109
110         lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g3
111         sllx    %g3, 16, %g3
112         or      %g3, %g4, %g4
113
114         lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g3
115         sllx    %g3, 24, %g3
116         or      %g3, %g4, %g4
117
118         lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g3
119         sllx    %g3, 32, %g3
120         or      %g3, %g4, %g4
121
122         lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g3
123         sllx    %g3, 40, %g3
124         or      %g3, %g4, %g4
125
126         lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g3
127         sllx    %g3, 48, %g3
128         or      %g3, %g4, %g4
129
130         lduba   [%g5] ASI_PHYS_BYPASS_EC_E, %g3
131         sllx    %g3, 56, %g3
132         or      %g3, %g4, %g1
133         ! %g1 contains end of memory
134
135         setx    _end, %g7, %g3
136         set     0x7ffff, %g2
137         add     %g3, %g2, %g3
138         andn    %g3, %g2, %g3
139         setx    _data, %g7, %g2
140         sub     %g3, %g2, %g2
141         sub     %g1, %g2, %g2                   ! %g2 = start of private memory
142         mov     %g2, %l0
143
144         ! setup .data & .bss
145         setx    _data, %g7, %g4
146         sub     %g3, %g4, %g5
147         srlx    %g5, 19, %g6                    ! %g6 = # of 512k .bss pages
148         set     0xc0000000, %g3
149         sllx    %g3, 32, %g3
150         or      %g3, 0x76, %g3
151         ! valid, 512k, locked, cacheable(I/E/C), priv, writable
152         set     48, %g7
153 1:      stxa    %g4, [%g7] ASI_DMMU             ! vaddr = _data + N * 0x80000, ctx=0
154         or      %g2, %g3, %g5
155         ! paddr = start_mem + N * 0x80000
156         stxa    %g5, [%g0] ASI_DTLB_DATA_IN
157         set     0x80000, %g5
158         add     %g2, %g5, %g2
159         add     %g4, %g5, %g4
160         deccc   %g6
161         bne     1b
162          nop
163
164         ! setup .rodata, also make .text readable
165         setx    _data, %g7, %g5
166         setx    _start, %g7, %g4
167         sub     %g5, %g4, %g5
168         srlx    %g5, 19, %g6                    ! %g6 = # of 512k .rodata pages
169         set     48, %g7
170         set     0x80000, %g5
171         setx    PROM_ADDR, %l1, %l2
172 1:      stxa    %g4, [%g7] ASI_DMMU             ! vaddr = _rodata, ctx=0
173         set     0xc0000000, %g3
174         sllx    %g3, 32, %g3
175         or      %g3, 0x74, %g3
176         or      %l2, %g3, %g3
177         ! valid, 512k, locked, cacheable(I/E/C), priv
178         ! paddr = _rodata + N * 0x10000
179         stxa    %g3, [%g0] ASI_DTLB_DATA_IN
180         add     %g4, %g5, %g4
181         deccc   %g6
182         bne     1b
183          add    %l2, %g5, %l2
184
185         membar  #Sync
186
187         setx    _start, %g7, %g4
188         setx    _rodata, %g7, %g5
189         sub     %g5, %g4, %g5
190         set 0x7ffff, %g7
191         add %g5, %g7, %g5                                       ! round to 512k
192         srlx    %g5, 19, %g6                    ! %g6 = # of 512k .text pages
193         set     0x80000, %g5
194         set     48, %g7
195         setx    PROM_ADDR, %l1, %l2
196 1:      stxa    %g4, [%g7] ASI_IMMU             ! vaddr = _start, ctx=0
197         set     0xc0000000, %g3
198         sllx    %g3, 32, %g3
199         or      %g3, 0x74, %g3
200         or      %l2, %g3, %g3
201         ! valid, 512k, locked, cacheable(I/E/C), priv
202         ! paddr = _start + N * 0x80000
203         stxa    %g3, [%g0] ASI_ITLB_DATA_IN
204         add     %g4, %g5, %g4
205         deccc   %g6
206         bne     1b
207          add    %l2, %g5, %l2
208
209         flush   %g4
210
211         mov     %g1, %g3
212
213         set     8, %g2
214         sta     %g0, [%g2] ASI_DMMU             ! set primary ctx=0
215
216         ! Enable I/D MMUs and caches
217         setx    lowmem, %g2, %g1
218         set     LSU_CONTROL_DM|LSU_CONTROL_IM|LSU_CONTROL_DC|LSU_CONTROL_IC, %g2
219         jmp     %g1
220          stxa   %g2, [%g0] ASI_LSU_CONTROL
221
222 lowmem:
223         /* Copy the DATA section from ROM. */
224         setx    _data - 8, %o7, %o0             ! First address of DATA
225         setx    _bss, %o7, %o1                  ! Last address of DATA
226         setx    _start, %o7, %o2
227         sub     %o0, %o2, %o2                   ! _data - _start
228         setx    PROM_ADDR, %o7, %o3
229         add     %o3, %o2, %o2                   ! PROM_ADDR + (_data - _start)
230         ba      2f
231          nop
232 1:
233         ldxa    [%o2] ASI_PHYS_BYPASS_EC_E, %g1
234         stx     %g1, [%o0]
235 2:
236         add     %o2, 0x8, %o2
237         subcc   %o0, %o1, %g0
238         bl      1b
239          add    %o0, 0x8, %o0
240
241         /* Zero out our BSS section. */
242         setx    _bss - 8, %o7, %o0              ! First address of BSS
243         setx    _end - 8, %o7, %o1                  ! Last address of BSS
244         ba      2f
245          nop
246 1:
247         stx     %g0, [%o0]
248 2:
249         subcc   %o0, %o1, %g0
250         bl      1b
251          add    %o0, 0x8, %o0
252
253         setx    trap_table, %g2, %g1
254         wrpr    %g1, %tba
255
256         setx    qemu_mem_size, %g7, %g1
257         stx     %g3, [%g1]
258
259         setx    _data, %g7, %g1                 ! Store va->pa conversion factor
260         sub     %g1, %l0, %g2
261         setx    va_shift, %g7, %g1
262         stx     %g2, [%g1]
263
264         /* Finally, turn on traps so that we can call c-code. */
265         wrpr    %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate
266
267         ! 100 Hz timer
268         setx    TICK_INT_DIS, %g2, %g1
269         rd      %tick, %g2
270         andn    %g2, %g1, %g2
271         set     HZ, %g1
272         add     %g1, %g2, %g1
273         wr      %g1, 0, %tick_cmpr
274
275         /* Switch to our main context.
276          * Main context is statically defined in C.
277          */
278
279         call    __switch_context_nosave
280          nop
281
282         /* We get here when the main context switches back to
283          * the boot context.
284          */
285 bad_conf:
286         b       bad_conf
287          nop