1 /* $NetBSD: pal.S,v 1.2 2023/10/06 11:45:16 skrll Exp $ */ 2 3 /*- 4 * Copyright (c) 2000-2001 Doug Rabson 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD$ 29 */ 30 31 #include <machine/asm.h> 32 33 .data 34 .global ia64_pal_entry 35 ia64_pal_entry: .quad 0 36 .text 37 38 /* 39 * struct ia64_pal_result ia64_call_pal_static(u_int64_t proc, 40 * u_int64_t arg1, u_int64_t arg2, u_int64_t arg3) 41 */ 42 ENTRY(ia64_call_pal_static, 4) 43 44 .regstk 4,5,0,0 45 palret = loc0 46 entry = loc1 47 rpsave = loc2 48 pfssave = loc3 49 psrsave = loc4 50 51 alloc pfssave=ar.pfs,4,5,0,0 52 ;; 53 mov rpsave=rp 54 55 movl entry=@gprel(ia64_pal_entry) 56 1: mov palret=ip // for return address 57 ;; 58 add entry=entry,gp 59 mov psrsave=psr 60 mov r28=in0 // procedure number 61 ;; 62 ld8 entry=[entry] // read entry point 63 mov r29=in1 // copy arguments 64 mov r30=in2 65 mov r31=in3 66 ;; 67 mov b6=entry 68 add palret=2f-1b,palret // calculate return address 69 ;; 70 mov b0=palret 71 rsm psr.i // disable interrupts 72 ;; 73 br.cond.sptk b6 // call into firmware 74 2: mov psr.l=psrsave 75 mov rp=rpsave 76 mov ar.pfs=pfssave 77 ;; 78 srlz.d 79 br.ret.sptk rp 80 81 END(ia64_call_pal_static) 82 83 #ifdef _KERNEL 84 85 /* 86 * struct ia64_pal_result ia64_call_pal_static_physical(u_int64_t proc, 87 * u_int64_t arg1, u_int64_t arg2, u_int64_t arg3) 88 */ 89 ENTRY(ia64_call_pal_static_physical, 4) 90 91 .regstk 4,5,0,0 92 palret = loc0 93 entry = loc1 94 rpsave = loc2 95 pfssave = loc3 96 psrsave = loc4 97 98 alloc pfssave=ar.pfs,4,5,0,0 99 ;; 100 mov rpsave=rp 101 102 movl entry=@gprel(ia64_pal_entry) 103 1: mov palret=ip // for return address 104 ;; 105 add entry=entry,gp 106 mov r28=in0 // procedure number 107 ;; 108 ld8 entry=[entry] // read entry point 109 mov r29=in1 // copy arguments 110 mov r30=in2 111 mov r31=in3 112 ;; 113 dep entry=0,entry,61,3 // physical address 114 dep palret=0,palret,61,3 // physical address 115 br.call.sptk.many rp=ia64_physical_mode 116 mov psrsave=ret0 117 ;; 118 mov b6=entry 119 add palret=2f-1b,palret // calculate return address 120 ;; 121 mov b0=palret 122 br.cond.sptk b6 // call into firmware 123 ;; 124 2: mov r14=psrsave 125 ;; 126 br.call.sptk.many rp=ia64_change_mode 127 ;; 128 mov rp=rpsave 129 mov ar.pfs=pfssave 130 ;; 131 br.ret.sptk rp 132 133 END(ia64_call_pal_static_physical) 134 135 #endif 136 137 /* 138 * struct ia64_pal_result ia64_call_pal_stacked(u_int64_t proc, 139 * u_int64_t arg1, u_int64_t arg2, u_int64_t arg3) 140 */ 141 ENTRY(ia64_call_pal_stacked, 4) 142 143 .regstk 4,4,4,0 144 entry = loc0 145 rpsave = loc1 146 pfssave = loc2 147 psrsave = loc3 148 149 alloc pfssave=ar.pfs,4,4,4,0 150 ;; 151 mov rpsave=rp 152 movl entry=@gprel(ia64_pal_entry) 153 ;; 154 add entry=entry,gp 155 mov psrsave=psr 156 mov r28=in0 // procedure number 157 mov out0=in0 158 ;; 159 ld8 entry=[entry] // read entry point 160 mov out1=in1 // copy arguments 161 mov out2=in2 162 mov out3=in3 163 ;; 164 mov b6=entry 165 ;; 166 rsm psr.i // disable interrupts 167 ;; 168 br.call.sptk.many rp=b6 // call into firmware 169 mov psr.l=psrsave 170 mov rp=rpsave 171 mov ar.pfs=pfssave 172 ;; 173 srlz.d 174 br.ret.sptk rp 175 176 END(ia64_call_pal_stacked) 177 178 #ifdef _KERNEL 179 180 /* 181 * struct ia64_pal_result ia64_call_pal_stacked_physical(u_int64_t proc, 182 * u_int64_t arg1, u_int64_t arg2, u_int64_t arg3) 183 */ 184 ENTRY(ia64_call_pal_stacked_physical, 4) 185 186 .regstk 4,4,4,0 187 entry = loc0 188 rpsave = loc1 189 pfssave = loc2 190 psrsave = loc3 191 192 alloc pfssave=ar.pfs,4,4,4,0 193 ;; 194 mov rpsave=rp 195 movl entry=@gprel(ia64_pal_entry) 196 ;; 197 add entry=entry,gp 198 mov r28=in0 // procedure number 199 mov out0=in0 200 ;; 201 ld8 entry=[entry] // read entry point 202 mov out1=in1 // copy arguments 203 mov out2=in2 204 mov out3=in3 205 ;; 206 dep entry=0,entry,61,3 // physical address 207 br.call.sptk.many rp=ia64_physical_mode 208 mov psrsave=ret0 209 ;; 210 mov b6=entry 211 ;; 212 br.call.sptk.many rp=b6 // call into firmware 213 ;; 214 mov r14=psrsave 215 ;; 216 br.call.sptk.many rp=ia64_change_mode 217 ;; 218 mov rp=rpsave 219 mov ar.pfs=pfssave 220 ;; 221 br.ret.sptk rp 222 223 END(ia64_call_pal_stacked_physical) 224 225 #endif 226