1129198Scognet/*	$NetBSD: locore.S,v 1.14 2003/04/20 16:21:40 thorpej Exp $	*/
2129198Scognet
3139735Simp/*-
4239268Sgonzo * Copyright 2011 Semihalf
5129198Scognet * Copyright (C) 1994-1997 Mark Brinicombe
6129198Scognet * Copyright (C) 1994 Brini
7129198Scognet * All rights reserved.
8129198Scognet *
9129198Scognet * Redistribution and use in source and binary forms, with or without
10129198Scognet * modification, are permitted provided that the following conditions
11129198Scognet * are met:
12129198Scognet * 1. Redistributions of source code must retain the above copyright
13129198Scognet *    notice, this list of conditions and the following disclaimer.
14129198Scognet * 2. Redistributions in binary form must reproduce the above copyright
15129198Scognet *    notice, this list of conditions and the following disclaimer in the
16129198Scognet *    documentation and/or other materials provided with the distribution.
17129198Scognet * 3. All advertising materials mentioning features or use of this software
18129198Scognet *    must display the following acknowledgement:
19129198Scognet *	This product includes software developed by Brini.
20129198Scognet * 4. The name of Brini may not be used to endorse or promote products
21129198Scognet *    derived from this software without specific prior written permission.
22129198Scognet *
23129198Scognet * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR
24129198Scognet * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25129198Scognet * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26129198Scognet * IN NO EVENT SHALL BRINI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27129198Scognet * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28129198Scognet * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29129198Scognet * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30129198Scognet * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31129198Scognet * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32129198Scognet * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33129198Scognet *
34129198Scognet */
35129198Scognet
36129198Scognet#include "assym.s"
37135640Scognet#include <sys/syscall.h>
38129198Scognet#include <machine/asm.h>
39129198Scognet#include <machine/armreg.h>
40295801Sskra#include <machine/pte-v4.h>
41236524Simp
42129198Scognet__FBSDID("$FreeBSD: stable/11/sys/arm/arm/locore-v4.S 331890 2018-04-02 22:02:49Z gonzo $");
43129198Scognet
44292523Sian/* 2K initial stack is plenty, it is only used by initarm() */
45292523Sian#define INIT_ARM_STACK_SIZE	2048
46273288Sandrew
47129198Scognet#define	CPWAIT_BRANCH							 \
48129198Scognet	sub	pc, pc, #4
49129198Scognet
50129198Scognet#define	CPWAIT(tmp)							 \
51129198Scognet	mrc	p15, 0, tmp, c2, c0, 0	/* arbitrary read of CP15 */	;\
52129198Scognet	mov	tmp, tmp		/* wait for it to complete */	;\
53129198Scognet	CPWAIT_BRANCH			/* branch to next insn */
54129198Scognet
55235277Simp/*
56273288Sandrew * This is for libkvm, and should be the address of the beginning
57235277Simp * of the kernel text segment (not necessarily the same as kernbase).
58273288Sandrew *
59273288Sandrew * These are being phased out. Newer copies of libkvm don't need these
60273288Sandrew * values as the information is added to the core file by inspecting
61273288Sandrew * the running kernel.
62235277Simp */
63129198Scognet	.text
64276596Sian	.align	2
65273288Sandrew#ifdef PHYSADDR
66129198Scognet.globl kernbase
67129198Scognet.set kernbase,KERNBASE
68150863Scognet.globl physaddr
69150863Scognet.set physaddr,PHYSADDR
70273288Sandrew#endif
71129198Scognet
72183878Sraj/*
73236524Simp * On entry for FreeBSD boot ABI:
74236524Simp *	r0 - metadata pointer or 0 (boothowto on AT91's boot2)
75218227Smarcel *	r1 - if (r0 == 0) then metadata pointer
76236524Simp * On entry for Linux boot ABI:
77236524Simp *	r0 - 0
78236524Simp *	r1 - machine type (passed as arg2 to initarm)
79236524Simp *	r2 - Pointer to a tagged list or dtb image (phys addr) (passed as arg1 initarm)
80236524Simp *
81236524Simp * For both types of boot we gather up the args, put them in a struct arm_boot_params
82236524Simp * structure and pass that to initarm.
83183878Sraj */
84269390Sian	.globl	btext
85269390Sianbtext:
86218227SmarcelASENTRY_NP(_start)
87250253Sian	STOP_UNWINDING		/* Can't unwind into the bootloader! */
88250253Sian
89236524Simp	mov	r9, r0		/* 0 or boot mode from boot2 */
90236524Simp	mov	r8, r1		/* Save Machine type */
91236524Simp	mov	ip, r2		/* Save meta data */
92266271Sgavin	mov	fp, r3		/* Future expansion */
93183878Sraj
94193846Smarcel	/* Make sure interrupts are disabled. */
95193846Smarcel	mrs	r7, cpsr
96271398Sandrew	orr	r7, r7, #(PSR_I | PSR_F)
97193846Smarcel	msr	cpsr_c, r7
98193846Smarcel
99166819Scognet#if defined (FLASHADDR) && defined(LOADERRAMADDR)
100292523Sian/*
101292523Sian * Sanity check the configuration.
102292523Sian * FLASHADDR and LOADERRAMADDR depend on PHYSADDR in some cases.
103292523Sian * ARMv4 and ARMv5 make assumptions on where they are loaded.
104292523Sian * TODO: Fix the ARMv4/v5 case.
105292523Sian */
106292523Sian#ifndef PHYSADDR
107292523Sian#error PHYSADDR must be defined for this configuration
108292523Sian#endif
109292523Sian
110166819Scognet	/* Check if we're running from flash. */
111166819Scognet	ldr	r7, =FLASHADDR
112175983Sraj	/*
113166819Scognet	 * If we're running with MMU disabled, test against the
114166819Scognet	 * physical address instead.
115166819Scognet	 */
116300533Sian	mrc	CP15_SCTLR(r2)
117166819Scognet	ands	r2, r2, #CPU_CONTROL_MMU_ENABLE
118236524Simp	ldreq	r6, =PHYSADDR
119236524Simp	ldrne	r6, =LOADERRAMADDR
120236524Simp	cmp	r7, r6
121166819Scognet	bls 	flash_lower
122166819Scognet	cmp	r7, pc
123166819Scognet	bhi	from_ram
124166819Scognet	b	do_copy
125282025Sandrew
126166819Scognetflash_lower:
127236524Simp	cmp	r6, pc
128166819Scognet	bls	from_ram
129166819Scognetdo_copy:
130236524Simp	ldr	r7, =KERNBASE
131175983Sraj	adr	r1, _start
132166819Scognet	ldr	r0, Lreal_start
133166819Scognet	ldr	r2, Lend
134166819Scognet	sub	r2, r2, r0
135236524Simp	sub	r0, r0, r7
136236524Simp	add	r0, r0, r6
137166819Scognet	mov	r4, r0
138166819Scognet	bl	memcpy
139166819Scognet	ldr	r0, Lram_offset
140166819Scognet	add	pc, r4, r0
141166819ScognetLram_offset:	.word from_ram-_C_LABEL(_start)
142166819Scognetfrom_ram:
143166819Scognet	nop
144135640Scognet#endif
145143681Sjmg
146166819Scognetdisable_mmu:
147135640Scognet	/* Disable MMU for a while */
148300533Sian	mrc	CP15_SCTLR(r2)
149153550Scognet	bic	r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\
150153550Scognet	    CPU_CONTROL_WBUF_ENABLE)
151153550Scognet	bic	r2, r2, #(CPU_CONTROL_IC_ENABLE)
152153550Scognet	bic	r2, r2, #(CPU_CONTROL_BPRD_ENABLE)
153300533Sian	mcr	CP15_SCTLR(r2)
154129198Scognet
155135640Scognet	nop
156135640Scognet	nop
157135640Scognet	nop
158271240Sandrew	CPWAIT(r0)
159271240Sandrew
160135640ScognetLunmapped:
161261227Sandrew	/*
162261227Sandrew	 * Build page table from scratch.
163261227Sandrew	 */
164261227Sandrew
165292523Sian	/*
166292523Sian	 * Figure out the physical address we're loaded at by assuming this
167292523Sian	 * entry point code is in the first L1 section and so if we clear the
168292523Sian	 * offset bits of the pc that will give us the section-aligned load
169292523Sian	 * address, which remains in r5 throughout all the following code.
170292523Sian	 */
171292523Sian	ldr	r2, =(L1_S_OFFSET)
172292523Sian	bic	r5, pc, r2
173292523Sian
174292523Sian	/* Find the delta between VA and PA, result stays in r0 throughout. */
175261855Sandrew	adr	r0, Lpagetable
176271232Sandrew	bl	translate_va_to_pa
177261855Sandrew
178292523Sian	/*
179292523Sian	 * First map the entire 4GB address space as VA=PA.  It's mapped as
180292523Sian	 * normal (cached) memory because it's for things like accessing the
181292523Sian	 * parameters passed in from the bootloader, which might be at any
182292523Sian	 * physical address, different for every platform.
183266849Scognet	 */
184292523Sian	mov	r1, #0
185292523Sian	mov	r2, #0
186292523Sian	mov	r3, #4096
187292523Sian	bl	build_pagetables
188292523Sian
189292523Sian	/*
190292523Sian	 * Next we do 64MiB starting at the physical load address, mapped to
191292523Sian	 * the VA the kernel is linked for.
192282025Sandrew	 */
193282025Sandrew	mov	r1, r5
194292523Sian	ldr	r2, =(KERNVIRTADDR)
195282025Sandrew	mov	r3, #64
196282025Sandrew	bl	build_pagetables
197331890Sgonzo#if defined(PHYSADDR) && (KERNVIRTADDR != KERNBASE)
198331890Sgonzo/*
199331890Sgonzo * If the kernel wasn't loaded at the beginning of the ram, map the memory
200331890Sgonzo * before the kernel too, as some ports use that for pagetables, stack, etc...
201331890Sgonzo */
202331890Sgonzo	ldr	r1, =PHYSADDR
203331890Sgonzo	ldr 	r2, =KERNBASE
204331890Sgonzo	ldr	r3, =((KERNVIRTADDR - KERNBASE) / L1_S_SIZE)
205331890Sgonzo	bl	build_pagetables
206331890Sgonzo#endif
207282025Sandrew
208292523Sian	/* Create a device mapping for early_printf if specified. */
209261606Sandrew#if defined(SOCDEV_PA) && defined(SOCDEV_VA)
210261783Simp	ldr	r1, =SOCDEV_PA
211261783Simp	ldr	r2, =SOCDEV_VA
212292523Sian	mov	r3, #1
213292523Sian	bl	build_device_pagetables
214261606Sandrew#endif
215129198Scognet
216129198Scognet	mcr	p15, 0, r0, c2, c0, 0	/* Set TTB */
217129198Scognet	mcr	p15, 0, r0, c8, c7, 0	/* Flush TLB */
218129198Scognet
219129198Scognet	/* Set the Domain Access register.  Very important! */
220282025Sandrew	mov	r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
221129198Scognet	mcr	p15, 0, r0, c3, c0, 0
222282025Sandrew	/*
223248961Sian	 * Enable MMU.
224248961Sian	 */
225300533Sian	mrc	CP15_SCTLR(r0)
226243602Sgonzo	orr	r0, r0, #(CPU_CONTROL_MMU_ENABLE)
227300533Sian	mcr	CP15_SCTLR(r0)
228153550Scognet	nop
229153550Scognet	nop
230153550Scognet	nop
231129198Scognet	CPWAIT(r0)
232129198Scognet
233292523Sian	/* Transition the PC from physical to virtual addressing. */
234292523Sian	ldr	pc,=mmu_done
235292523Sian
236129198Scognetmmu_done:
237153550Scognet	nop
238129198Scognet	adr	r1, .Lstart
239129198Scognet	ldmia	r1, {r1, r2, sp}	/* Set initial stack and */
240129198Scognet	sub	r2, r2, r1		/* get zero init data */
241129198Scognet	mov	r3, #0
242129198Scognet.L1:
243150863Scognet	str	r3, [r1], #0x0004	/* get zero init data */
244129198Scognet	subs	r2, r2, #4
245129198Scognet	bgt	.L1
246129198Scognet
247142145Scognetvirt_done:
248261663Sandrew	mov	r1, #28			/* loader info size is 28 bytes also second arg */
249236524Simp	subs	sp, sp, r1		/* allocate arm_boot_params struct on stack */
250261855Sandrew	mov	r0, sp			/* loader info pointer is first arg */
251247608Sandrew	bic	sp, sp, #7		/* align stack to 8 bytes */
252236524Simp	str	r1, [r0]		/* Store length of loader info */
253236524Simp	str	r9, [r0, #4]		/* Store r0 from boot loader */
254236524Simp	str	r8, [r0, #8]		/* Store r1 from boot loader */
255236524Simp	str	ip, [r0, #12]		/* store r2 from boot loader */
256236524Simp	str	fp, [r0, #16]		/* store r3 from boot loader */
257261562Sandrew	str	r5, [r0, #20]		/* store the physical address */
258261855Sandrew	adr	r4, Lpagetable		/* load the pagetable address */
259261855Sandrew	ldr	r5, [r4, #4]
260261663Sandrew	str	r5, [r0, #24]		/* store the pagetable address */
261175983Sraj	mov	fp, #0			/* trace back starts here */
262129198Scognet	bl	_C_LABEL(initarm)	/* Off we go */
263129198Scognet
264129198Scognet	/* init arm will return the new stack pointer. */
265129198Scognet	mov	sp, r0
266129198Scognet
267282024Sandrew	bl	_C_LABEL(mi_startup)	/* call mi_startup()! */
268129198Scognet
269129198Scognet	adr	r0, .Lmainreturned
270130164Sphk	b	_C_LABEL(panic)
271175983Sraj	/* NOTREACHED */
272261606SandrewEND(_start)
273261606Sandrew
274271232Sandrew#define VA_TO_PA_POINTER(name, table)	 \
275271232Sandrewname:					;\
276271232Sandrew	.word	.			;\
277271232Sandrew	.word	table
278271232Sandrew
279261606Sandrew/*
280271232Sandrew * Returns the physical address of a magic va to pa pointer.
281271232Sandrew * r0     - The pagetable data pointer. This must be built using the
282271232Sandrew *          VA_TO_PA_POINTER macro.
283271232Sandrew *          e.g.
284271232Sandrew *            VA_TO_PA_POINTER(Lpagetable, pagetable)
285271232Sandrew *            ...
286271232Sandrew *            adr  r0, Lpagetable
287271232Sandrew *            bl   translate_va_to_pa
288271232Sandrew *            r0 will now contain the physical address of pagetable
289271232Sandrew * r1, r2 - Trashed
290271232Sandrew */
291271232Sandrewtranslate_va_to_pa:
292271232Sandrew	ldr	r1, [r0]
293271232Sandrew	sub	r2, r1, r0
294271232Sandrew	/* At this point: r2 = VA - PA */
295271232Sandrew
296271232Sandrew	/*
297271232Sandrew	 * Find the physical address of the table. After these two
298271232Sandrew	 * instructions:
299271232Sandrew	 * r1 = va(pagetable)
300271232Sandrew	 *
301271232Sandrew	 * r0 = va(pagetable) - (VA - PA)
302271232Sandrew	 *    = va(pagetable) - VA + PA
303271232Sandrew	 *    = pa(pagetable)
304271232Sandrew	 */
305271232Sandrew	ldr	r1, [r0, #4]
306271232Sandrew	sub	r0, r1, r2
307271232Sandrew	RET
308271232Sandrew
309271232Sandrew/*
310261606Sandrew * Builds the page table
311261606Sandrew * r0 - The table base address
312261606Sandrew * r1 - The physical address (trashed)
313261606Sandrew * r2 - The virtual address (trashed)
314261606Sandrew * r3 - The number of 1MiB sections
315261606Sandrew * r4 - Trashed
316261606Sandrew *
317261606Sandrew * Addresses must be 1MiB aligned
318261606Sandrew */
319292523Sianbuild_device_pagetables:
320292523Sian	ldr	r4, =(L1_TYPE_S|L1_S_AP(AP_KRW))
321292523Sian	b	1f
322261606Sandrewbuild_pagetables:
323261606Sandrew	/* Set the required page attributed */
324261606Sandrew	ldr	r4, =(L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
325292523Sian1:
326261606Sandrew	orr	r1, r4
327261606Sandrew
328261606Sandrew	/* Move the virtual address to the correct bit location */
329261606Sandrew	lsr	r2, #(L1_S_SHIFT - 2)
330261606Sandrew
331261606Sandrew	mov	r4, r3
332292523Sian2:
333261606Sandrew	str	r1, [r0, r2]
334261606Sandrew	add	r2, r2, #4
335261606Sandrew	add	r1, r1, #(L1_S_SIZE)
336261606Sandrew	adds	r4, r4, #-1
337292523Sian	bhi	2b
338261606Sandrew
339261606Sandrew	RET
340261606Sandrew
341271232SandrewVA_TO_PA_POINTER(Lpagetable, pagetable)
342261855Sandrew
343166819ScognetLreal_start:
344166819Scognet	.word	_start
345261855SandrewLend:
346166819Scognet	.word	_edata
347261855Sandrew
348129198Scognet.Lstart:
349129198Scognet	.word	_edata
350261227Sandrew	.word	_ebss
351129198Scognet	.word	svcstk + INIT_ARM_STACK_SIZE
352129198Scognet
353153550Scognet.Lvirt_done:
354153550Scognet	.word	virt_done
355239268Sgonzo
356129198Scognet.Lmainreturned:
357129198Scognet	.asciz	"main() returned"
358276596Sian	.align	2
359129198Scognet
360129198Scognet	.bss
361129198Scognetsvcstk:
362129198Scognet	.space	INIT_ARM_STACK_SIZE
363129198Scognet
364261227Sandrew/*
365261227Sandrew * Memory for the initial pagetable. We are unable to place this in
366261227Sandrew * the bss as this will be cleared after the table is loaded.
367261227Sandrew */
368321049Semaste	.section ".init_pagetable", "aw", %nobits
369261227Sandrew	.align	14 /* 16KiB aligned */
370261227Sandrewpagetable:
371261227Sandrew	.space	L1_TABLE_SIZE
372261227Sandrew
373129198Scognet	.text
374276596Sian	.align	2
375129198Scognet
376143681Sjmg.Lcpufuncs:
377129198Scognet	.word	_C_LABEL(cpufuncs)
378129198Scognet
379135640ScognetENTRY_NP(cpu_halt)
380282025Sandrew	mrs	r2, cpsr
381129198Scognet	bic	r2, r2, #(PSR_MODE)
382282025Sandrew	orr	r2, r2, #(PSR_SVC32_MODE)
383271398Sandrew	orr	r2, r2, #(PSR_I | PSR_F)
384282025Sandrew	msr	cpsr_fsxc, r2
385129198Scognet
386129198Scognet	ldr	r4, .Lcpu_reset_address
387129198Scognet	ldr	r4, [r4]
388129198Scognet
389129198Scognet	ldr	r0, .Lcpufuncs
390129198Scognet	mov	lr, pc
391129198Scognet	ldr	pc, [r0, #CF_IDCACHE_WBINV_ALL]
392183839Sraj	mov	lr, pc
393183839Sraj	ldr	pc, [r0, #CF_L2CACHE_WBINV_ALL]
394129198Scognet
395129198Scognet	/*
396129198Scognet	 * Load the cpu_reset_needs_v4_MMU_disable flag to determine if it's
397129198Scognet	 * necessary.
398129198Scognet	 */
399129198Scognet
400129198Scognet	ldr	r1, .Lcpu_reset_needs_v4_MMU_disable
401129198Scognet	ldr	r1, [r1]
402129198Scognet	cmp	r1, #0
403129198Scognet	mov	r2, #0
404129198Scognet
405129198Scognet	/*
406175983Sraj	 * MMU & IDC off, 32 bit program & data space
407129198Scognet	 * Hurl ourselves into the ROM
408129198Scognet	 */
409129198Scognet	mov	r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE)
410300533Sian	mcr	CP15_SCTLR(r0)
411282025Sandrew	mcrne	p15, 0, r2, c8, c7, 0 	/* nail I+D TLB on ARMv4 and greater */
412282025Sandrew	mov	pc, r4
413129198Scognet
414129198Scognet	/*
415129198Scognet	 * _cpu_reset_address contains the address to branch to, to complete
416129198Scognet	 * the cpu reset after turning the MMU off
417129198Scognet	 * This variable is provided by the hardware specific code
418129198Scognet	 */
419129198Scognet.Lcpu_reset_address:
420129198Scognet	.word	_C_LABEL(cpu_reset_address)
421129198Scognet
422129198Scognet	/*
423129198Scognet	 * cpu_reset_needs_v4_MMU_disable contains a flag that signals if the
424129198Scognet	 * v4 MMU disable instruction needs executing... it is an illegal instruction
425129198Scognet	 * on f.e. ARM6/7 that locks up the computer in an endless illegal
426129198Scognet	 * instruction / data-abort / reset loop.
427129198Scognet	 */
428129198Scognet.Lcpu_reset_needs_v4_MMU_disable:
429129198Scognet	.word	_C_LABEL(cpu_reset_needs_v4_MMU_disable)
430248361SandrewEND(cpu_halt)
431129198Scognet
432129198Scognet
433129198Scognet/*
434129198Scognet * setjump + longjmp
435129198Scognet */
436129198ScognetENTRY(setjmp)
437129198Scognet	stmia	r0, {r4-r14}
438129198Scognet	mov	r0, #0x00000000
439137463Scognet	RET
440248361SandrewEND(setjmp)
441129198Scognet
442129198ScognetENTRY(longjmp)
443129198Scognet	ldmia	r0, {r4-r14}
444129198Scognet	mov	r0, #0x00000001
445137463Scognet	RET
446248361SandrewEND(longjmp)
447129198Scognet
448129198Scognet	.data
449282024Sandrew	.global	_C_LABEL(esym)
450129198Scognet_C_LABEL(esym):	.word	_C_LABEL(end)
451129198Scognet
452129198ScognetENTRY_NP(abort)
453129198Scognet	b	_C_LABEL(abort)
454248361SandrewEND(abort)
455129198Scognet
456135640ScognetENTRY_NP(sigcode)
457135640Scognet	mov	r0, sp
458262903Sian	add	r0, r0, #SIGF_UC
459245414Sandrew
460245414Sandrew	/*
461245414Sandrew	 * Call the sigreturn system call.
462282024Sandrew	 *
463245414Sandrew	 * We have to load r7 manually rather than using
464245414Sandrew	 * "ldr r7, =SYS_sigreturn" to ensure the value of szsigcode is
465245414Sandrew	 * correct. Using the alternative places esigcode at the address
466245414Sandrew	 * of the data rather than the address one past the data.
467245414Sandrew	 */
468245414Sandrew
469245414Sandrew	ldr	r7, [pc, #12]	/* Load SYS_sigreturn */
470135640Scognet	swi	SYS_sigreturn
471135640Scognet
472135640Scognet	/* Well if that failed we better exit quick ! */
473135640Scognet
474245414Sandrew	ldr	r7, [pc, #8]	/* Load SYS_exit */
475135640Scognet	swi	SYS_exit
476135640Scognet
477245414Sandrew	/* Branch back to retry SYS_sigreturn */
478245414Sandrew	b	. - 16
479269390SianEND(sigcode)
480245414Sandrew	.word	SYS_sigreturn
481245414Sandrew	.word	SYS_exit
482245414Sandrew
483276596Sian	.align	2
484135640Scognet	.global _C_LABEL(esigcode)
485135640Scognet		_C_LABEL(esigcode):
486143681Sjmg
487135640Scognet	.data
488135640Scognet	.global szsigcode
489135640Scognetszsigcode:
490135640Scognet	.long esigcode-sigcode
491269390Sian
492129198Scognet/* End of locore.S */
493