xref: /kvm-unit-tests/arm/cstart64.S (revision 5a2a737123ec35985030e2151bb07a803d0390bd)
139ac3f84SAndrew Jones/*
239ac3f84SAndrew Jones * Boot entry point and assembler functions for aarch64 tests.
339ac3f84SAndrew Jones *
449f758b8SAndrew Jones * Copyright (C) 2017, Red Hat Inc, Andrew Jones <drjones@redhat.com>
539ac3f84SAndrew Jones *
649f758b8SAndrew Jones * This work is licensed under the terms of the GNU GPL, version 2.
739ac3f84SAndrew Jones */
839ac3f84SAndrew Jones#define __ASSEMBLY__
962bdc67fSAndrew Jones#include <auxinfo.h>
1039ac3f84SAndrew Jones#include <asm/asm-offsets.h>
11b5f659beSAlexandru Elisei#include <asm/assembler.h>
127ee966e9SAndrew Jones#include <asm/ptrace.h>
13db328a24SAndrew Jones#include <asm/page.h>
14db328a24SAndrew Jones#include <asm/pgtable-hwdef.h>
15993c37beSAndrew Jones#include <asm/thread_info.h>
161dd3501aSAlexandru Elisei#include <asm/sysreg.h>
17993c37beSAndrew Jones
18993c37beSAndrew Jones.macro zero_range, tmp1, tmp2
19993c37beSAndrew Jones9998:	cmp	\tmp1, \tmp2
20993c37beSAndrew Jones	b.eq	9997f
21993c37beSAndrew Jones	stp	xzr, xzr, [\tmp1], #16
22993c37beSAndrew Jones	b	9998b
23993c37beSAndrew Jones9997:
24993c37beSAndrew Jones.endm
2539ac3f84SAndrew Jones
2639ac3f84SAndrew Jones.section .init
2739ac3f84SAndrew Jones
28f6416021SAndrew Jones/*
29f6416021SAndrew Jones * Bootloader params are in x0-x3. See kernel doc
30f6416021SAndrew Jones * Documentation/arm64/booting.txt
31f6416021SAndrew Jones */
3239ac3f84SAndrew Jones.globl start
3339ac3f84SAndrew Jonesstart:
34f6416021SAndrew Jones	/* get our base address */
35f6416021SAndrew Jones	adrp	x4, start
36f6416021SAndrew Jones	add     x4, x4, :lo12:start
37f6416021SAndrew Jones
3839ac3f84SAndrew Jones	/*
39f6416021SAndrew Jones	 * Update all R_AARCH64_RELATIVE relocations using the table
40f6416021SAndrew Jones	 * of Elf64_Rela entries between reloc_start/end. The build
41f6416021SAndrew Jones	 * will not emit other relocation types.
42f6416021SAndrew Jones	 *
43f6416021SAndrew Jones	 * struct Elf64_Rela {
44f6416021SAndrew Jones	 * 	uint64_t r_offset;
45f6416021SAndrew Jones	 * 	uint64_t r_info;
46f6416021SAndrew Jones	 * 	int64_t  r_addend;
47f6416021SAndrew Jones	 * }
4839ac3f84SAndrew Jones	 */
49f6416021SAndrew Jones	adrp	x5, reloc_start
50f6416021SAndrew Jones	add     x5, x5, :lo12:reloc_start
51f6416021SAndrew Jones	adrp	x6, reloc_end
52f6416021SAndrew Jones	add     x6, x6, :lo12:reloc_end
53f6416021SAndrew Jones1:
54f6416021SAndrew Jones	cmp	x5, x6
55f6416021SAndrew Jones	b.hs	1f
56f6416021SAndrew Jones	ldr	x7, [x5]			// r_offset
57f6416021SAndrew Jones	ldr	x8, [x5, #16]			// r_addend
58f6416021SAndrew Jones	add	x8, x8, x4			// val = base + r_addend
59f6416021SAndrew Jones	str	x8, [x4, x7]			// base[r_offset] = val
60f6416021SAndrew Jones	add	x5, x5, #24
61f6416021SAndrew Jones	b	1b
62f6416021SAndrew Jones
63f6416021SAndrew Jones1:
64993c37beSAndrew Jones	/* zero BSS */
65993c37beSAndrew Jones	adrp	x4, bss
66993c37beSAndrew Jones	add	x4, x4, :lo12:bss
67993c37beSAndrew Jones	adrp    x5, ebss
68993c37beSAndrew Jones	add     x5, x5, :lo12:ebss
69993c37beSAndrew Jones	zero_range x4, x5
70993c37beSAndrew Jones
71993c37beSAndrew Jones	/* zero and set up stack */
72993c37beSAndrew Jones	adrp    x5, stacktop
73993c37beSAndrew Jones	add     x5, x5, :lo12:stacktop
74993c37beSAndrew Jones	sub	x4, x5, #THREAD_SIZE
75993c37beSAndrew Jones	zero_range x4, x5
7610b65ce7SAlexandru Elisei
7710b65ce7SAlexandru Elisei	/* set SCTLR_EL1 to a known value */
7810b65ce7SAlexandru Elisei	ldr	x4, =INIT_SCTLR_EL1_MMU_OFF
7910b65ce7SAlexandru Elisei	msr	sctlr_el1, x4
8010b65ce7SAlexandru Elisei	isb
8110b65ce7SAlexandru Elisei
821693644dSAndrew Jones	mov	x4, #1
831693644dSAndrew Jones	msr	spsel, x4
8463ab2d70SPaolo Bonzini	adrp    x4, stackptr
8563ab2d70SPaolo Bonzini	add     sp, x4, :lo12:stackptr
8639ac3f84SAndrew Jones
87f6416021SAndrew Jones	/* enable FP/ASIMD */
88f6416021SAndrew Jones	mov	x4, #(3 << 20)
89f6416021SAndrew Jones	msr	cpacr_el1, x4
9039ac3f84SAndrew Jones
9139ac3f84SAndrew Jones	/* set up exception handling */
927ee966e9SAndrew Jones	bl	exceptions_init
9339ac3f84SAndrew Jones
9439ac3f84SAndrew Jones	/* complete setup */
95*5a2a7371SAndrew Jones	adrp	x1, stacktop
96*5a2a7371SAndrew Jones	add	x1, x1, :lo12:stacktop		// x1 is the base of free memory
97f6416021SAndrew Jones	bl	setup				// x0 is the addr of the dtb
9839ac3f84SAndrew Jones
9939ac3f84SAndrew Jones	/* run the test */
10063ab2d70SPaolo Bonzini	adrp	x0, __argc
101364bb39dSAndrew Jones	ldr	w0, [x0, :lo12:__argc]
10263ab2d70SPaolo Bonzini	adrp	x1, __argv
10363ab2d70SPaolo Bonzini	add	x1, x1, :lo12:__argv
10463ab2d70SPaolo Bonzini	adrp	x2, __environ
10563ab2d70SPaolo Bonzini	add	x2, x2, :lo12:__environ
10639ac3f84SAndrew Jones	bl	main
10739ac3f84SAndrew Jones	bl	exit
10839ac3f84SAndrew Jones	b	halt
10939ac3f84SAndrew Jones
11039ac3f84SAndrew Jones.text
11139ac3f84SAndrew Jones
11262bdc67fSAndrew Jonesget_mmu_off:
11362bdc67fSAndrew Jones	adrp	x0, auxinfo
11462bdc67fSAndrew Jones	ldr	x0, [x0, :lo12:auxinfo + 8]
11562bdc67fSAndrew Jones	and	x0, x0, #AUXINFO_MMU_OFF
11662bdc67fSAndrew Jones	ret
11762bdc67fSAndrew Jones
11868ea0e0bSAndrew Jones.globl secondary_entry
11968ea0e0bSAndrew Jonessecondary_entry:
12068ea0e0bSAndrew Jones	/* Enable FP/ASIMD */
12168ea0e0bSAndrew Jones	mov	x0, #(3 << 20)
12268ea0e0bSAndrew Jones	msr	cpacr_el1, x0
12368ea0e0bSAndrew Jones
12468ea0e0bSAndrew Jones	/* set up exception handling */
12568ea0e0bSAndrew Jones	bl	exceptions_init
12668ea0e0bSAndrew Jones
12762bdc67fSAndrew Jones	/* enable the MMU unless requested off */
12862bdc67fSAndrew Jones	bl	get_mmu_off
12962bdc67fSAndrew Jones	cbnz	x0, 1f
13063ab2d70SPaolo Bonzini	adrp	x0, mmu_idmap
13163ab2d70SPaolo Bonzini	ldr	x0, [x0, :lo12:mmu_idmap]
13268ea0e0bSAndrew Jones	bl	asm_mmu_enable
13368ea0e0bSAndrew Jones
13462bdc67fSAndrew Jones1:
13568ea0e0bSAndrew Jones	/* set the stack */
13663ab2d70SPaolo Bonzini	adrp	x0, secondary_data
13763ab2d70SPaolo Bonzini	ldr	x0, [x0, :lo12:secondary_data]
13868ea0e0bSAndrew Jones	mov	sp, x0
13968ea0e0bSAndrew Jones
14068ea0e0bSAndrew Jones	/* finish init in C code */
14168ea0e0bSAndrew Jones	bl	secondary_cinit
14268ea0e0bSAndrew Jones
14368ea0e0bSAndrew Jones	/* x0 is now the entry function, run it */
144543ce33cSAndrew Jones	blr	x0
1459246de4cSAndrew Jones	b	do_idle
14668ea0e0bSAndrew Jones
14739ac3f84SAndrew Jones.globl halt
14839ac3f84SAndrew Joneshalt:
14939ac3f84SAndrew Jones1:	wfi
15039ac3f84SAndrew Jones	b	1b
1517ee966e9SAndrew Jones
1527ee966e9SAndrew Jones/*
153db328a24SAndrew Jones * asm_mmu_enable
154db328a24SAndrew Jones *   Inputs:
155db328a24SAndrew Jones *     x0 is the base address of the translation table
156db328a24SAndrew Jones *   Outputs: none
157db328a24SAndrew Jones *
158db328a24SAndrew Jones * Adapted from
159db328a24SAndrew Jones *   arch/arm64/kernel/head.S
160db328a24SAndrew Jones *   arch/arm64/mm/proc.S
161db328a24SAndrew Jones */
162db328a24SAndrew Jones
163db328a24SAndrew Jones/*
164db328a24SAndrew Jones * Memory region attributes for LPAE:
165db328a24SAndrew Jones *
166db328a24SAndrew Jones *   n = AttrIndx[2:0]
167db328a24SAndrew Jones *                      n       MAIR
168db328a24SAndrew Jones *   DEVICE_nGnRnE      000     00000000
169db328a24SAndrew Jones *   DEVICE_nGnRE       001     00000100
170db328a24SAndrew Jones *   DEVICE_GRE         010     00001100
171db328a24SAndrew Jones *   NORMAL_NC          011     01000100
172db328a24SAndrew Jones *   NORMAL             100     11111111
173cc70e4b6SNikos Nikoleris *   NORMAL_WT          101     10111011
174cc70e4b6SNikos Nikoleris *   DEVICE_nGRE        110     00001000
175db328a24SAndrew Jones */
176db328a24SAndrew Jones#define MAIR(attr, mt) ((attr) << ((mt) * 8))
177db328a24SAndrew Jones
178a2d06852SNikos Nikoleris#if PAGE_SIZE == SZ_64K
179a2d06852SNikos Nikoleris#define TCR_TG_FLAGS	TCR_TG0_64K | TCR_TG1_64K
180a2d06852SNikos Nikoleris#elif PAGE_SIZE == SZ_16K
181a2d06852SNikos Nikoleris#define TCR_TG_FLAGS	TCR_TG0_16K | TCR_TG1_16K
182a2d06852SNikos Nikoleris#elif PAGE_SIZE == SZ_4K
183a2d06852SNikos Nikoleris#define TCR_TG_FLAGS	TCR_TG0_4K | TCR_TG1_4K
184a2d06852SNikos Nikoleris#endif
185a2d06852SNikos Nikoleris
186db328a24SAndrew Jones.globl asm_mmu_enable
187db328a24SAndrew Jonesasm_mmu_enable:
18842d51704SAlexandru Elisei	tlbi	vmalle1			// invalidate I + D TLBs
18942d51704SAlexandru Elisei	dsb	nsh
190db328a24SAndrew Jones
191db328a24SAndrew Jones	/* TCR */
192db328a24SAndrew Jones	ldr	x1, =TCR_TxSZ(VA_BITS) |		\
193a2d06852SNikos Nikoleris		     TCR_TG_FLAGS  |			\
194db328a24SAndrew Jones		     TCR_IRGN_WBWA | TCR_ORGN_WBWA |	\
1958425ac5cSAlexandru Elisei		     TCR_SHARED |			\
1968425ac5cSAlexandru Elisei		     TCR_EPD1
197d140ad48SAndrew Jones	mrs	x2, id_aa64mmfr0_el1
198db328a24SAndrew Jones	bfi	x1, x2, #32, #3
199db328a24SAndrew Jones	msr	tcr_el1, x1
200db328a24SAndrew Jones
201db328a24SAndrew Jones	/* MAIR */
202db328a24SAndrew Jones	ldr	x1, =MAIR(0x00, MT_DEVICE_nGnRnE) |	\
203db328a24SAndrew Jones		     MAIR(0x04, MT_DEVICE_nGnRE) |	\
204db328a24SAndrew Jones		     MAIR(0x0c, MT_DEVICE_GRE) |	\
205db328a24SAndrew Jones		     MAIR(0x44, MT_NORMAL_NC) |		\
206cc70e4b6SNikos Nikoleris		     MAIR(0xff, MT_NORMAL) |	        \
207cc70e4b6SNikos Nikoleris		     MAIR(0xbb, MT_NORMAL_WT) |         \
208cc70e4b6SNikos Nikoleris		     MAIR(0x08, MT_DEVICE_nGRE)
209db328a24SAndrew Jones	msr	mair_el1, x1
210db328a24SAndrew Jones
211db328a24SAndrew Jones	/* TTBR0 */
212db328a24SAndrew Jones	msr	ttbr0_el1, x0
213db328a24SAndrew Jones	isb
214db328a24SAndrew Jones
215db328a24SAndrew Jones	/* SCTLR */
216db328a24SAndrew Jones	mrs	x1, sctlr_el1
217db328a24SAndrew Jones	orr	x1, x1, SCTLR_EL1_C
218db328a24SAndrew Jones	orr	x1, x1, SCTLR_EL1_I
219db328a24SAndrew Jones	orr	x1, x1, SCTLR_EL1_M
220db328a24SAndrew Jones	msr	sctlr_el1, x1
221db328a24SAndrew Jones	isb
222db328a24SAndrew Jones
223db328a24SAndrew Jones	ret
224db328a24SAndrew Jones
225e27b176bSAndrew Jones.globl asm_mmu_disable
226e27b176bSAndrew Jonesasm_mmu_disable:
227e27b176bSAndrew Jones	mrs	x0, sctlr_el1
228e27b176bSAndrew Jones	bic	x0, x0, SCTLR_EL1_M
229e27b176bSAndrew Jones	msr	sctlr_el1, x0
230e27b176bSAndrew Jones	isb
231410b3bf0SAlexandru Elisei
232410b3bf0SAlexandru Elisei	/* Clean + invalidate the entire memory */
233410b3bf0SAlexandru Elisei	adrp	x0, __phys_offset
234410b3bf0SAlexandru Elisei	ldr	x0, [x0, :lo12:__phys_offset]
235410b3bf0SAlexandru Elisei	adrp	x1, __phys_end
236410b3bf0SAlexandru Elisei	ldr	x1, [x1, :lo12:__phys_end]
237b5f659beSAlexandru Elisei	sub	x1, x1, x0
238410b3bf0SAlexandru Elisei	dcache_by_line_op civac, sy, x0, x1, x2, x3
239410b3bf0SAlexandru Elisei
240e27b176bSAndrew Jones	ret
241e27b176bSAndrew Jones
242db328a24SAndrew Jones/*
2437ee966e9SAndrew Jones * Vectors
2442da0f98cSAndrew Jones */
2452da0f98cSAndrew Jones
2462da0f98cSAndrew Jonesexceptions_init:
2472da0f98cSAndrew Jones	adrp	x4, vector_table
2482da0f98cSAndrew Jones	add	x4, x4, :lo12:vector_table
2492da0f98cSAndrew Jones	msr	vbar_el1, x4
2502da0f98cSAndrew Jones	isb
2512da0f98cSAndrew Jones	ret
2522da0f98cSAndrew Jones
2532da0f98cSAndrew Jones/*
2542da0f98cSAndrew Jones * Vector stubs
2557ee966e9SAndrew Jones * Adapted from arch/arm64/kernel/entry.S
2567ee966e9SAndrew Jones */
2577ee966e9SAndrew Jones.macro vector_stub, name, vec
2587ee966e9SAndrew Jones\name:
2597ee966e9SAndrew Jones	stp	 x0,  x1, [sp, #-S_FRAME_SIZE]!
2607ee966e9SAndrew Jones	stp	 x2,  x3, [sp,  #16]
2617ee966e9SAndrew Jones	stp	 x4,  x5, [sp,  #32]
2627ee966e9SAndrew Jones	stp	 x6,  x7, [sp,  #48]
2637ee966e9SAndrew Jones	stp	 x8,  x9, [sp,  #64]
2647ee966e9SAndrew Jones	stp	x10, x11, [sp,  #80]
2657ee966e9SAndrew Jones	stp	x12, x13, [sp,  #96]
2667ee966e9SAndrew Jones	stp	x14, x15, [sp, #112]
2677ee966e9SAndrew Jones	stp	x16, x17, [sp, #128]
2687ee966e9SAndrew Jones	stp	x18, x19, [sp, #144]
2697ee966e9SAndrew Jones	stp	x20, x21, [sp, #160]
2707ee966e9SAndrew Jones	stp	x22, x23, [sp, #176]
2717ee966e9SAndrew Jones	stp	x24, x25, [sp, #192]
2727ee966e9SAndrew Jones	stp	x26, x27, [sp, #208]
2737ee966e9SAndrew Jones	stp	x28, x29, [sp, #224]
2747ee966e9SAndrew Jones
2757ee966e9SAndrew Jones	str	x30, [sp, #S_LR]
2767ee966e9SAndrew Jones
2777ee966e9SAndrew Jones	.if \vec >= 8
2787ee966e9SAndrew Jones	mrs	x1, sp_el0
2797ee966e9SAndrew Jones	.else
2807ee966e9SAndrew Jones	add	x1, sp, #S_FRAME_SIZE
2817ee966e9SAndrew Jones	.endif
2827ee966e9SAndrew Jones	str	x1, [sp, #S_SP]
2837ee966e9SAndrew Jones
2847ee966e9SAndrew Jones	mrs	x1, elr_el1
2857ee966e9SAndrew Jones	mrs	x2, spsr_el1
2867ee966e9SAndrew Jones	stp	x1, x2, [sp, #S_PC]
2877ee966e9SAndrew Jones
288f6d10793SAndrew Jones	mov	x0, \vec
2897ee966e9SAndrew Jones	mov	x1, sp
2907ee966e9SAndrew Jones	mrs	x2, esr_el1
2917ee966e9SAndrew Jones	bl	do_handle_exception
2927ee966e9SAndrew Jones
2937ee966e9SAndrew Jones	ldp	x1, x2, [sp, #S_PC]
2947ee966e9SAndrew Jones	msr	spsr_el1, x2
2957ee966e9SAndrew Jones	msr	elr_el1, x1
2967ee966e9SAndrew Jones
2977ee966e9SAndrew Jones	.if \vec >= 8
2987ee966e9SAndrew Jones	ldr	x1, [sp, #S_SP]
2997ee966e9SAndrew Jones	msr	sp_el0, x1
3007ee966e9SAndrew Jones	.endif
3017ee966e9SAndrew Jones
3027ee966e9SAndrew Jones	ldr	x30, [sp, #S_LR]
3037ee966e9SAndrew Jones
3047ee966e9SAndrew Jones	ldp	x28, x29, [sp, #224]
3057ee966e9SAndrew Jones	ldp	x26, x27, [sp, #208]
3067ee966e9SAndrew Jones	ldp	x24, x25, [sp, #192]
3077ee966e9SAndrew Jones	ldp	x22, x23, [sp, #176]
3087ee966e9SAndrew Jones	ldp	x20, x21, [sp, #160]
3097ee966e9SAndrew Jones	ldp	x18, x19, [sp, #144]
3107ee966e9SAndrew Jones	ldp	x16, x17, [sp, #128]
3117ee966e9SAndrew Jones	ldp	x14, x15, [sp, #112]
3127ee966e9SAndrew Jones	ldp	x12, x13, [sp,  #96]
3137ee966e9SAndrew Jones	ldp	x10, x11, [sp,  #80]
3147ee966e9SAndrew Jones	ldp	 x8,  x9, [sp,  #64]
3157ee966e9SAndrew Jones	ldp	 x6,  x7, [sp,  #48]
3167ee966e9SAndrew Jones	ldp	 x4,  x5, [sp,  #32]
3177ee966e9SAndrew Jones	ldp	 x2,  x3, [sp,  #16]
3187ee966e9SAndrew Jones	ldp	 x0,  x1, [sp], #S_FRAME_SIZE
3197ee966e9SAndrew Jones
3207ee966e9SAndrew Jones	eret
3217ee966e9SAndrew Jones.endm
3227ee966e9SAndrew Jones
3237ee966e9SAndrew Jonesvector_stub	el1t_sync,     0
3247ee966e9SAndrew Jonesvector_stub	el1t_irq,      1
3257ee966e9SAndrew Jonesvector_stub	el1t_fiq,      2
3267ee966e9SAndrew Jonesvector_stub	el1t_error,    3
3277ee966e9SAndrew Jones
3287ee966e9SAndrew Jonesvector_stub	el1h_sync,     4
3297ee966e9SAndrew Jonesvector_stub	el1h_irq,      5
3307ee966e9SAndrew Jonesvector_stub	el1h_fiq,      6
3317ee966e9SAndrew Jonesvector_stub	el1h_error,    7
3327ee966e9SAndrew Jones
3337ee966e9SAndrew Jonesvector_stub	el0_sync_64,   8
3347ee966e9SAndrew Jonesvector_stub	el0_irq_64,    9
3357ee966e9SAndrew Jonesvector_stub	el0_fiq_64,   10
3367ee966e9SAndrew Jonesvector_stub	el0_error_64, 11
3377ee966e9SAndrew Jones
3387ee966e9SAndrew Jonesvector_stub	el0_sync_32,  12
3397ee966e9SAndrew Jonesvector_stub	el0_irq_32,   13
3407ee966e9SAndrew Jonesvector_stub	el0_fiq_32,   14
3417ee966e9SAndrew Jonesvector_stub	el0_error_32, 15
3427ee966e9SAndrew Jones
3437ee966e9SAndrew Jones.section .text.ex
3447ee966e9SAndrew Jones
3457ee966e9SAndrew Jones.macro ventry, label
3467ee966e9SAndrew Jones.align 7
3477ee966e9SAndrew Jones	b	\label
3487ee966e9SAndrew Jones.endm
3497ee966e9SAndrew Jones
3507ee966e9SAndrew Jones.align 11
3517ee966e9SAndrew Jonesvector_table:
3527ee966e9SAndrew Jones	ventry	el1t_sync			// Synchronous EL1t
3537ee966e9SAndrew Jones	ventry	el1t_irq			// IRQ EL1t
3547ee966e9SAndrew Jones	ventry	el1t_fiq			// FIQ EL1t
3557ee966e9SAndrew Jones	ventry	el1t_error			// Error EL1t
3567ee966e9SAndrew Jones
3577ee966e9SAndrew Jones	ventry	el1h_sync			// Synchronous EL1h
3587ee966e9SAndrew Jones	ventry	el1h_irq			// IRQ EL1h
3597ee966e9SAndrew Jones	ventry	el1h_fiq			// FIQ EL1h
3607ee966e9SAndrew Jones	ventry	el1h_error			// Error EL1h
3617ee966e9SAndrew Jones
3627ee966e9SAndrew Jones	ventry	el0_sync_64			// Synchronous 64-bit EL0
3637ee966e9SAndrew Jones	ventry	el0_irq_64			// IRQ 64-bit EL0
3647ee966e9SAndrew Jones	ventry	el0_fiq_64			// FIQ 64-bit EL0
3657ee966e9SAndrew Jones	ventry	el0_error_64			// Error 64-bit EL0
3667ee966e9SAndrew Jones
3677ee966e9SAndrew Jones	ventry	el0_sync_32			// Synchronous 32-bit EL0
3687ee966e9SAndrew Jones	ventry	el0_irq_32			// IRQ 32-bit EL0
3697ee966e9SAndrew Jones	ventry	el0_fiq_32			// FIQ 32-bit EL0
3707ee966e9SAndrew Jones	ventry	el0_error_32			// Error 32-bit EL0
371