1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
/*
* PAL Firmware support
* IA-64 Processor Programmers Reference Vol 2
*
* Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
* Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
* Copyright (C) 1999 David Mosberger <davidm@hpl.hp.com>
*/
.text
.psr abi64
.psr lsb
.lsb
.data
pal_entry_point:
data8 ia64_pal_default_handler
.text
/*
* Set the PAL entry point address. This could be written in C code, but we do it here
* to keep it all in one module (besides, it's so trivial that it's
* not a big deal).
*
* in0 Address of the PAL entry point (text address, NOT a function descriptor).
*/
.align 16
.global ia64_pal_handler_init
.proc ia64_pal_handler_init
ia64_pal_handler_init:
alloc r3=ar.pfs,1,0,0,0
movl r2=pal_entry_point
;;
st8 [r2]=in0
br.ret.sptk.few rp
.endp ia64_pal_handler_init
/*
* Default PAL call handler. This needs to be coded in assembly because it uses
* the static calling convention, i.e., the RSE may not be used and calls are
* done via "br.cond" (not "br.call").
*/
.align 16
.global ia64_pal_default_handler
.proc ia64_pal_default_handler
ia64_pal_default_handler:
mov r8=-1
br.cond.sptk.few rp
/*
* Make a PAL call using the static calling convention.
*
* in0 Pointer to struct ia64_pal_retval
* in1 Index of PAL service
* in2 - in4 Remaning PAL arguments
*
*/
#ifdef __GCC_MULTIREG_RETVALS__
# define arg0 in0
# define arg1 in1
# define arg2 in2
# define arg3 in3
# define arg4 in4
#else
# define arg0 in1
# define arg1 in2
# define arg2 in3
# define arg3 in4
# define arg4 in5
#endif
.text
.psr abi64
.psr lsb
.lsb
.align 16
.global ia64_pal_call_static
.proc ia64_pal_call_static
ia64_pal_call_static:
alloc loc0 = ar.pfs,6,90,0,0
movl loc2 = pal_entry_point
1: {
mov r28 = arg0
mov r29 = arg1
mov r8 = ip
}
;;
ld8 loc2 = [loc2] // loc2 <- entry point
mov r30 = arg2
mov r31 = arg3
;;
mov loc3 = psr
mov loc1 = rp
adds r8 = .ret0-1b,r8
;;
rsm psr.i
mov b7 = loc2
mov rp = r8
;;
br.cond.sptk.few b7
.ret0: mov psr.l = loc3
#ifndef __GCC_MULTIREG_RETVALS__
st8 [in0] = r8, 8
;;
st8 [in0] = r9, 8
;;
st8 [in0] = r10, 8
;;
st8 [in0] = r11, 8
#endif
mov ar.pfs = loc0
mov rp = loc1
;;
srlz.d // seralize restoration of psr.l
br.ret.sptk.few b0
.endp ia64_pal_call_static
|