1/* 2 * Copyright 2021 The Hafnium Authors. 3 * 4 * Use of this source code is governed by a BSD-style 5 * license that can be found in the LICENSE file or at 6 * https://opensource.org/licenses/BSD-3-Clause. 7 */ 8 9.macro ffa_mem_perm_set start:req end:req perm:req 10 adrp x29, \start 11 add x29, x29, :lo12: \start 12 13 adrp x30, \end 14 add x30, x30, :lo12:\end 15 16 /* x30 = end - begin */ 17 sub x30, x30, x29 18 /* x28 = x30 >> 12 (number of pages) */ 19 mov x28, #12 20 lsrv x28, x30, x28 21 22 /* 0x84000089 is function identifier for FFA_MEM_PERM_SET_32 */ 23 mov w0, #0x89 24 movk w0, #0x8400, lsl #16 25 mov x1, x29 26 mov x2, x28 27 mov w3, #\perm 28 29 svc #0 30 31 /* 0x84000061 is function identifier for FFA_SUCCESS_32 */ 32 mov w1, #0x61 33 movk w1, #0x8400, lsl #16 34 cmp w1, w0 35 b.ne . 36.endm 37 38.section .init.entry, "ax" 39.global entry 40entry: 41 /* Linux aarch64 image header. */ 42 b 0f 43 .word 0 44 .quad 0x1000 /* text_offset */ 45 .quad image_size /* image_size */ 46 .quad 0 /* flags */ 47 .quad 0 /* res2 */ 48 .quad 0 /* res3 */ 49 .quad 0 /* res4 */ 50 .word 0x644d5241 /* magic */ 51 .word 0 52 530: 54 /* Save data (fdt pointer or mem size) passed by hypervisor. */ 55 mov x10, x0 56 57 /* Set everything other than text as RW, so that relocations can succeed. */ 58 ffa_mem_perm_set rodata_begin image_end 5 59 60 /* 61 * Calculate the difference between the actual load address and the 62 * preferred one. We'll use this to relocate. 63 */ 64 adrp x25, entry 65 add x25, x25, :lo12:entry 66 67 ldr w29, =ORIGIN_ADDRESS 68 69 sub x25, x25, x29 70 71 /* Find where the relocations begin and end. */ 72 adrp x29, rela_begin 73 add x29, x29, :lo12:rela_begin 74 75 adrp x30, rela_end 76 add x30, x30, :lo12:rela_end 77 78 /* Iterate over all relocations. */ 791: cmp x29, x30 80 b.eq 2f 81 82 ldp x26, x27, [x29], #16 83 ldr x28, [x29], #8 84 85 cmp w27, #1027 /* R_AARCH64_RELATIVE */ 86 b.ne . 87 88 add x28, x28, x25 89 str x28, [x26, x25] 90 b 1b 91 92 /* Set everything between ro data and data begin as RO */ 932: ffa_mem_perm_set rodata_begin data_begin 7 94 95 /* set everthing else as RW */ 96 ffa_mem_perm_set data_begin image_end 5 97 98 /* Zero out the bss section. */ 99 adrp x29, bss_begin 100 add x29, x29, :lo12:bss_begin 101 102 adrp x30, bss_end 103 add x30, x30, :lo12:bss_end 104 1053: cmp x29, x30 106 b.hs 4f 107 108 stp xzr, xzr, [x29], #16 109 b 3b 110 1114: mov x0, x10 112 113 /* Branch to the entry point for the specific image. */ 114 b image_entry 115 116.section .init.image_entry, "ax" 117.global image_entry 118image_entry: 119 /* Prepare the stack. */ 120 adr x30, kstack + 4096 121 mov sp, x30 122 123 /* Call into C code. */ 124 bl kmain 125 126 /* Loop forever waiting for interrupts. */ 1270: wfi 128 b 0b 129