xref: /netbsd-src/sys/arch/hpc/stand/hpcboot/arm/arm.asm (revision 404fbe5fb94ca1e054339640cabb2801ce52dd30)
1;	$NetBSD: arm.asm,v 1.8 2008/05/03 23:49:14 martin Exp $
2;
3; Copyright (c) 2001 The NetBSD Foundation, Inc.
4; All rights reserved.
5;
6; This code is derived from software contributed to The NetBSD Foundation
7; by UCHIYAMA Yasushi.
8;
9; Redistribution and use in source and binary forms, with or without
10; modification, are permitted provided that the following conditions
11; are met:
12; 1. Redistributions of source code must retain the above copyright
13;    notice, this list of conditions and the following disclaimer.
14; 2. Redistributions in binary form must reproduce the above copyright
15;    notice, this list of conditions and the following disclaimer in the
16;    documentation and/or other materials provided with the distribution.
17;
18; THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21; PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28; POSSIBILITY OF SUCH DAMAGE.
29;
30
31;
32;armasm.exe $(InputPath)
33;arm.obj
34;
35	; dummy buffer for WritebackDCache
36	EXPORT	|dcachebuf|	[DATA]
37	AREA	|.data|, DATA
38|dcachebuf|
39	%	8192	; D-cache size
40
41	AREA	|.text|, CODE, PIC
42
43	;
44	; Operation mode ops.
45	;
46	EXPORT	|SetSVCMode|
47|SetSVCMode| PROC
48	mrs	r0, cpsr
49	bic	r0, r0, #0x1f
50	orr	r0, r0, #0x13
51	msr	cpsr, r0
52	mov	pc, lr
53	ENDP  ; |SetSVCMode|
54	EXPORT	|SetSystemMode|
55|SetSystemMode| PROC
56	mrs	r0, cpsr
57	orr	r0, r0, #0x1f
58	msr	cpsr, r0
59	mov	pc, lr
60	ENDP  ; |SetSystemMode|
61
62	;
63	; Interrupt ops.
64	;
65	EXPORT	|DI|
66|DI| PROC
67	mrs	r0, cpsr
68	orr	r0, r0, #0xc0
69	msr	cpsr, r0
70	mov	pc, lr
71	ENDP  ; |DI|
72	EXPORT	|EI|
73|EI| PROC
74	mrs	r0, cpsr
75	bic	r0, r0, #0xc0
76	msr	cpsr, r0
77	mov	pc, lr
78	ENDP  ; |EI|
79
80	;
81	; Cache ops.
82	;
83	EXPORT	|InvalidateICache|
84|InvalidateICache| PROC
85	; c7	(CRn) Cache Control Register
86	; c5, 0	(CRm, opcode_2) Flush I
87	; r0	(Rd) ignored
88	mcr	p15, 0, r0, c7, c5, 0
89	mov	pc, lr
90	ENDP  ; |InvalidateICache|
91
92	EXPORT	|WritebackDCache|
93|WritebackDCache| PROC
94	ldr	r0, [pc, #16]	; dcachebuf
95	add	r1, r0, #8192	; cache-size is 8Kbyte.
96|wbdc1|
97	ldr	r2, [r0], #32	; line-size is 32byte.
98	teq	r1, r0
99	bne	|wbdc1|
100	mov	pc, lr
101	DCD	|dcachebuf|
102	ENDP  ; |WritebackDCache|
103
104	EXPORT	|InvalidateDCache|
105|InvalidateDCache| PROC
106	; c7	(CRn) Cache Control Register
107	; c6, 0	(CRm, opcode_2) Flush D
108	; r0	(Rd) ignored
109	mcr	p15, 0, r0, c7, c6, 0
110	mov	pc, lr
111	ENDP  ; |InvalidateDCache|
112
113	EXPORT	|WritebackInvalidateDCache|
114|WritebackInvalidateDCache| PROC
115	ldr	r0, [pc, #20]	; dcachebuf
116	add	r1, r0, #8192
117|wbidc1|
118	ldr	r2, [r0], #32
119	teq	r1, r0
120	bne	|wbidc1|
121	mcr	p15, 0, r0, c7, c6, 0
122	mov	pc, lr
123	DCD	|dcachebuf|
124	ENDP  ; |WritebackInvalidateDCache|
125
126	;
127	; WriteBuffer ops
128	;
129	EXPORT	|WritebufferFlush|
130|WritebufferFlush| PROC
131	; c7	(CRn) Cache Control Register
132	; c10, 4(CRm, opcode_2) Flush D
133	; r0	(Rd) ignored
134	mcr	p15, 0, r0, c7, c10, 4
135	mov	pc, lr
136	ENDP  ; |WritebufferFlush|
137
138	;
139	;	TLB ops.
140	;
141	EXPORT	|FlushIDTLB|
142|FlushIDTLB| PROC
143	mcr	p15, 0, r0, c8, c7, 0
144	mov	pc, lr
145	ENDP  ; |FlushIDTLB|
146
147	EXPORT	|FlushITLB|
148|FlushITLB| PROC
149	mcr	p15, 0, r0, c8, c5, 0
150	mov	pc, lr
151	ENDP  ; |FlushITLB|
152
153	EXPORT	|FlushDTLB|
154|FlushDTLB| PROC
155	mcr	p15, 0, r0, c8, c6, 0
156	mov	pc, lr
157	ENDP  ; |FlushITLB|
158
159	EXPORT	|FlushDTLBS|
160|FlushDTLBS| PROC
161	mcr	p15, 0, r0, c8, c6, 1
162	mov	pc, lr
163	ENDP  ; |FlushITLBS|
164
165	;
166	;	CurrentProgramStatusRegister access.
167	;
168	EXPORT	|GetCPSR|
169|GetCPSR| PROC
170	mrs	r0, cpsr
171	mov	pc, lr
172	ENDP  ; |GetCPSR|
173
174	EXPORT	|SetCPSR|
175|SetCPSR| PROC
176	msr	cpsr, r0
177	mov	pc, lr
178	ENDP  ; |SetCPSR|
179
180	;
181	;	SA-1100 Coprocessor15 access.
182	;
183; Reg0	ID (R)
184	EXPORT	|GetCop15Reg0|
185|GetCop15Reg0| PROC
186	mrc	p15, 0, r0, c0, c0, 0
187	; 0x4401a119 (44|01 = version 4|A11 = SA1100|9 = E stepping)
188	mov	pc, lr
189	ENDP  ; |GetCop15Reg0|
190
191; Reg1	Control (R/W)
192	EXPORT	|GetCop15Reg1|
193|GetCop15Reg1| PROC
194	mrc	p15, 0, r0, c1, c0, 0
195	; 0xc007327f (||...........|||..||..|..|||||||)
196	;	0 (1)MMU enabled
197	;	1 (1)Address fault enabled
198	;	2 (1)D-cache enabled
199	;	3 (1)Write-buffer enabled
200	;	7 (0)little-endian
201	;	8 (0)MMU protection (System)
202	;	9 (1)MMU protection (ROM)
203	;	12 (1)I-cache enabled
204	;	13 (1)Base address of interrupt vector is 0xffff0000
205	mov	pc, lr
206	ENDP  ; |GetCop15Reg1|
207	EXPORT	|SetCop15Reg1|
208|SetCop15Reg1| PROC
209	mcr	p15, 0, r0, c1, c0, 0
210	nop
211	nop
212	nop
213	mov	pc, lr
214	ENDP  ; |SetCop15Reg1|
215
216; Reg2	Translation table base (R/W)
217	EXPORT	|GetCop15Reg2|
218|GetCop15Reg2| PROC
219	mrc	p15, 0, r0, c2, c0, 0
220	mov	pc, lr
221	ENDP  ; |GetCop15Reg2|
222	EXPORT	|SetCop15Reg2|
223|SetCop15Reg2| PROC
224	mcr	p15, 0, r0, c2, c0, 0
225	mov	pc, lr
226	ENDP  ; |SetCop15Reg2|
227
228; Reg3	Domain access control (R/W)
229	EXPORT	|GetCop15Reg3|
230|GetCop15Reg3| PROC
231	mrc	p15, 0, r0, c3, c0, 0
232	mov	pc, lr
233	ENDP  ; |GetCop15Reg3|
234	EXPORT	|SetCop15Reg3|
235|SetCop15Reg3| PROC
236	mcr	p15, 0, r0, c3, c0, 0
237	mov	pc, lr
238	ENDP  ; |SetCop15Reg3|
239
240; Reg5	Fault status (R/W)
241	EXPORT	|GetCop15Reg5|
242|GetCop15Reg5| PROC
243	mrc	p15, 0, r0, c5, c0, 0
244	mov	pc, lr
245	ENDP  ; |GetCop15Reg5|
246
247; Reg6	Fault address (R/W)
248	EXPORT	|GetCop15Reg6|
249|GetCop15Reg6| PROC
250	mrc	p15, 0, r0, c6, c0, 0
251	mov	pc, lr
252	ENDP  ; |GetCop15Reg6|
253
254; Reg7	Cache operations (W)
255	; -> Cache ops
256; Reg8	TLB operations (Flush) (W)
257	; -> TLB ops
258; Reg9	Read buffer operations (W)
259; Reg13	Process ID (R/W)
260	EXPORT	|GetCop15Reg13|
261|GetCop15Reg13| PROC
262	mrc	p15, 0, r0, c13, c0, 0
263	mov	pc, lr
264	ENDP  ; |GetCop15Reg13|
265	EXPORT	|SetCop15Reg13|
266|SetCop15Reg13| PROC
267	mcr	p15, 0, r0, c13, c0, 0
268	mov	pc, lr
269	ENDP  ; |SetCop15Reg13|
270
271; Reg14	Breakpoint (R/W)
272	EXPORT	|GetCop15Reg14|
273|GetCop15Reg14| PROC
274	mrc	p15, 0, r0, c14, c0, 0
275	mov	pc, lr
276	ENDP  ; |GetCop15Reg14|
277; Reg15	Test, clock, and idle (W)
278
279	; FlatJump (kaddr_t bootinfo, kaddr_t pvec, kaddr_t stack
280	;		kaddr_t jump)
281	;	bootinfo	boot information block address.
282	;	pvec		page vector of kernel.
283	;	stack		physical address of stack
284	;	jump		physical address of boot function
285	; *** MMU and pipeline behavier are SA-1100 specific. ***
286	EXPORT	|FlatJump|
287|FlatJump| PROC
288	; disable interrupt
289	mrs	r4, cpsr
290	orr	r4, r4, #0xc0
291	msr	cpsr, r4
292	; disable MMU, I/D-Cache, Writebuffer.
293	; interrupt vector address is 0xffff0000
294	; 32bit exception handler/address range.
295	ldr	r4, [pc, #24]
296	; Disable WB/Cache/MMU
297	mcr	p15, 0, r4, c1, c0, 0
298	; Invalidate I/D-cache.
299	mcr	p15, 0, r4, c7, c7, 0	; Fetch translated	fetch
300	; Invalidate TLB entries.
301	mcr	p15, 0, r4, c8, c7, 0	; Fetch translated	decode
302	; jump to kernel entry physical address.
303	mov	pc, r3			; Fetch translated	execute
304	; NOTREACHED
305	nop				; Fetch nontranslated	cache access
306	nop				; Fetch nontranslated	writeback
307	mov	pc, lr			; Fetch nontranslated
308	DCD	0x00002030
309	ENDP  ; |FlatJump|
310;
311;	UART test
312;
313	; boot_func (uint32_t mapaddr, uint32_t bootinfo, uint32_t flags)
314	;
315	EXPORT	|boot_func|
316|boot_func| PROC
317	nop				; Cop15 hazard
318	nop				; Cop15 hazard
319	nop				; Cop15 hazard
320	mov	sp, r2			; set bootloader stack
321;	mov	r4, r0
322;	mov	r5, r1
323;	bl	colorbar
324;	mov	r0, r4
325;	mov	r1, r5
326	bl	boot
327	nop	; NOTREACHED
328	nop
329	ENDP  ; |boot_func|
330
331	EXPORT |colorbar|
332|colorbar| PROC
333	stmfd	sp!, {r4-r7, lr}
334	adr	r4, |$FBADDR|
335	ldr	r4, [r4]
336
337	mov	r7, #8
338	add	r0, r0, r7
339|color_loop|
340	mov	r6, r0
341	and	r6, r6, #7
342	orr	r6, r6, r6, LSL #8
343	orr	r6, r6, r6, LSL #16
344	add	r5, r4, #0x9600
345|fb_loop|
346	str	r6, [r4], #4
347	cmp	r4, r5
348	blt	|fb_loop|
349
350	subs	r7, r7, #1
351	bne	|color_loop|
352
353	ldmfd	sp!, {r4-r7, pc}
354|$FBADDR|
355	DCD	0xc0003000	; use WindowsCE default.
356	ENDP  ; |colorbar|
357
358	EXPORT	|boot|
359|boot| PROC
360;
361;	UART test code
362;
363;	; print boot_info address (r0) and page_vector start address (r1).
364;	mov	r4, r0
365;	mov	r5, r1
366;	mov	r0, #'I'
367;	bl	btputc
368;	mov	r0, r4
369;	bl	hexdump
370;	mov	r0, #'P'
371;	bl	btputc
372;	mov	r0, r5
373;	bl	hexdump
374;	mov	r7, r4
375;	mov	r2, r5		; start
376
377	mov	r7, r0		; if enabled above debug print, remove this.
378	mov	r2, r1		; if enabled above debug print, remove this.
379|page_loop|
380	mvn	r0, #0		; ~0
381	cmp	r2, r0
382	beq	|page_end|	; if (next == ~0) goto page_end
383
384	mov	r1, r2		; p = next
385	ldr	r2, [r1]	; next
386	ldr	r3, [r1, #4]	; src
387	ldr	r4, [r1, #8]	; dst
388	ldr	r5, [r1, #12]	; sz
389
390	cmp	r3, r0
391	add	r6, r4, r5	; end address
392	bne	|page_memcpy4|	; if (src != ~0) goto page_memcpy4
393
394	mov	r0, #0
395|page_memset|			; memset (dst, 0, sz) uncached.
396	str	r0, [r4], #4
397	cmp	r4, r6
398	blt	|page_memset|
399	b	|page_loop|
400
401|page_memcpy4|			; memcpy (dst, src, sz) uncached.
402	ldr	r0, [r3], #4
403	ldr	r5, [r3], #4
404	str	r0, [r4], #4
405	cmp	r4, r6
406	strlt	r5, [r4], #4
407	cmplt	r4, r6
408	blt	|page_memcpy4|
409
410	b	|page_loop|
411|page_end|
412	;
413	; jump to kernel
414	;
415;	mov	r0, #'E'
416;	bl	btputc
417;	ldr	r0, [r7]
418;	bl	hexdump
419;	ldr	r0, [r7]
420;	ldr	r0, [r0]
421;	bl	hexdump
422
423	; set stack pointer
424	mov	r5, #4096
425	add	r6, r6, #8192
426	sub	r5, r5, #1
427	bic	sp, r6, r5
428
429	; set bootargs
430	ldr	r4, [r7]
431	ldr	r0, [r7, #4]
432	ldr	r1, [r7, #8]
433	ldr	r2, [r7, #12]
434	mov	pc, r4
435	; NOTREACHED
436
437|infinite_loop|
438	nop
439	nop
440	nop
441	nop
442	nop
443	b	|infinite_loop|
444	ENDP  ; |boot|
445
446|btputc| PROC
447	adr	r1, |$UARTTXBSY|
448	ldr	r1, [r1]
449|btputc_busy|
450	ldr	r2, [r1]
451	and	r2, r2, #1
452	cmp	r2, #1
453	beq	|btputc_busy|
454	adr	r1, |$UARTTXADR|
455	ldr	r1, [r1]
456	str	r0, [r1]
457	mov	pc, lr
458	ENDP	;|btputc|
459
460|hexdump| PROC
461	stmfd	sp!, {r4-r5, lr}
462	mov	r4, r0
463	mov	r0, #0x30
464	bl	btputc
465	mov	r0, #0x78
466	bl	btputc
467	mov	r0, r4
468	;	Transmit register address
469	adr	r1, |$UARTTXADR|
470	ldr	r1, [r1]
471	;	Transmit busy register address
472	adr	r2, |$UARTTXBSY|
473	ldr	r2, [r2]
474	mov	r5, #8
475|hex_loop|
476	mov	r3, r0, LSR #28
477	cmp	r3, #9
478	addgt	r3, r3, #0x41 - 10
479	addle	r3, r3, #0x30
480|hex_busyloop|
481	 ldr	r4, [r2]
482	and	r4, r4, #1
483	cmp	r4, #1
484	beq	|hex_busyloop|
485	str	r3, [r1]
486	mov	r0, r0, LSL #4
487	subs	r5, r5, #1
488	bne	|hex_loop|
489	mov	r0, #0x0d
490	bl	btputc
491	mov	r0, #0x0a
492	bl	btputc
493	ldmfd	sp!, {r4-r5, pc}
494	ENDP	;|hexdump|
495
496|$UARTTXADR|
497	DCD	0x80050014
498|$UARTTXBSY|
499	DCD	0x80050020
500
501	EXPORT	|boot_func_end| [ DATA ]
502|boot_func_end|	DCD	0x0
503
504	END
505