~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/skiboot/external/opal-prd/thunk.S

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <endian.h>
 
2
#include <asm/unistd.h>
 
3
 
 
4
#ifndef __NR_switch_endian
 
5
#define __NR_switch_endian 363
 
6
#endif
 
7
 
 
8
/* a constant to use in the SI field of a little-endian D-form instruction */
 
9
#define le_si16(x) (((x & 0xff) << 24) | ((x & 0xff00) << 8))
 
10
 
 
11
        .text
 
12
 
 
13
        /*
 
14
         * Call into a HBRT BE function
 
15
         * Func desc (opd) will be in BE
 
16
         * Use ldbrx to load from opd
 
17
         */
 
18
 
 
19
call_be:
 
20
 
 
21
        /* Before we switch, we need to perform some ABI
 
22
         * conversion. We are currently running LE with the
 
23
         * new ABI v2. The GPR content is the same, we do
 
24
         * need save/restore and adjust r2. At this point r11
 
25
         * contain the OPD
 
26
         */
 
27
        nop
 
28
        nop
 
29
 
 
30
        /* We first create a stack frame compatible with BE, we
 
31
         * do a big one just in case... we save LR into our caller's
 
32
         * frame and r2 in our own frame. This is a BE formatted
 
33
         * frame so we store it as 40(r1), not 24(r1)
 
34
         */
 
35
        stdu %r1,-128(%r1)
 
36
        mflr %r0
 
37
        std %r0,(128 + 16)(%r1)
 
38
        std %r2,40(%r1)
 
39
 
 
40
        /* Grab the target r2 and function pointer */
 
41
#if __BYTE_ORDER == __LITTLE_ENDIAN
 
42
        ldbrx %r0, 0, %r11
 
43
        li %r2, 8
 
44
        ldbrx %r2, %r2, %r11
 
45
#else
 
46
        ld %r0,0(%r11)
 
47
        ld %r2,8(%r11)
 
48
#endif
 
49
 
 
50
        mtlr %r0
 
51
 
 
52
#if __BYTE_ORDER == __LITTLE_ENDIAN
 
53
        /* Switch to the "other endian" */
 
54
        li %r0,__NR_switch_endian
 
55
        sc
 
56
 
 
57
        /* Branch to LR */
 
58
        .long 0x2100804e /* (byteswapped blrl) */
 
59
 
 
60
        /* Switch endian back */
 
61
        .long 0x00000038 | le_si16(__NR_switch_endian)
 
62
                        /* byteswapped li %r0,__NR_switch_endian */
 
63
        .long 0x02000044 /* byteswapped sc */
 
64
#else
 
65
        bctrl
 
66
#endif
 
67
        /* Recover our r2, LR, undo stack frame ... */
 
68
        ld %r2,40(%r1)
 
69
        ld  %r0,(128+16)(%r1)
 
70
        addi %r1,%r1,128
 
71
        mtlr %r0
 
72
        blr
 
73
 
 
74
#define CALL_THUNK(name, idx)                    \
 
75
        .globl call_##name                      ;\
 
76
call_##name:                                    ;\
 
77
        ld %r11,hservice_runtime_fixed@got(%r2) ;\
 
78
        ld %r11,(idx * 8)(%r11)                 ;\
 
79
        b call_be
 
80
 
 
81
        /* Instanciate call to HBRT thunks */
 
82
        CALL_THUNK(cxxtestExecute, 1)
 
83
        CALL_THUNK(get_lid_list, 2)
 
84
        CALL_THUNK(occ_load, 3)
 
85
        CALL_THUNK(occ_start, 4)
 
86
        CALL_THUNK(occ_stop, 5)
 
87
        CALL_THUNK(process_occ_error, 6)
 
88
        CALL_THUNK(enable_attns, 7)
 
89
        CALL_THUNK(disable_attns, 8)
 
90
        CALL_THUNK(handle_attns, 9)
 
91
        CALL_THUNK(process_occ_reset, 10)
 
92
        CALL_THUNK(enable_occ_actuation, 11)
 
93
        CALL_THUNK(apply_attr_override, 12)
 
94
        CALL_THUNK(mfg_htmgt_pass_thru, 13)
 
95
        CALL_THUNK(run_command, 14)
 
96
 
 
97
        .globl call_hbrt_init
 
98
call_hbrt_init:
 
99
        ld %r11,hbrt_entry@got(%r2)
 
100
        b call_be
 
101
 
 
102
#if __BYTE_ORDER == __LITTLE_ENDIAN
 
103
        /* Callback from HBRT, stack conversion and call into C code,
 
104
         * we arrive here from the thunk macro with r11 containing the
 
105
         * target function and r2 already set from the OPD.
 
106
         */
 
107
call_le:
 
108
        /* Create a LE stack frame, save LR */
 
109
        stdu %r1,-32(%r1)
 
110
        mflr %r0
 
111
        std %r0,(32+16)(%r1)
 
112
 
 
113
        /* Branch to original function */
 
114
        mtlr    %r11
 
115
        blrl
 
116
 
 
117
        /* Restore stack and LR */
 
118
        ld  %r0,(32+16)(%r1)
 
119
        addi %r1,%r1,32
 
120
        mtlr %r0
 
121
 
 
122
        /* Switch endian back to BE */
 
123
        li %r0,__NR_switch_endian
 
124
        sc
 
125
 
 
126
        /* Return to BE */
 
127
        .long 0x2000804e /* byteswapped blr */
 
128
 
 
129
        /* Callback from HBRT. There is one entry point per function.
 
130
         *
 
131
         * We assume the proper r2 is already set via the OPD, so we grab our
 
132
         * target function pointer in r11 and jump to call_le
 
133
         */
 
134
#define CALLBACK_THUNK(name)                                                     \
 
135
        .pushsection ".text","ax"                                               ;\
 
136
        .globl  name##_thunk                                                    ;\
 
137
name##_thunk:                                                                   ;\
 
138
        .long 0x00000038 | le_si16(__NR_switch_endian)                          ;\
 
139
                        /* byteswapped li %r0,__NR_switch_endian */             ;\
 
140
        .long 0x02000044 /* byteswapped sc */                                   ;\
 
141
        ld %r11,name@got(%r2)                                                   ;\
 
142
        b call_le                                                               ;\
 
143
        .popsection                                                             ;\
 
144
        .pushsection ".data.thunk_opd","aw"                                     ;\
 
145
1:      .llong name##_thunk, .TOC., 0                                           ;\
 
146
        .popsection                                                             ;\
 
147
        .llong 1b
 
148
#else /* __BYTE_ORDER == __LITTLE_ENDIAN */
 
149
#define CALLBACK_THUNK(name)                                                     \
 
150
        .llong name
 
151
#endif
 
152
 
 
153
#define DISABLED_THUNK(name) .llong 0x0
 
154
 
 
155
        /* Here's the callback table generation. It creates the table and
 
156
         * all the thunks for all the callbacks from HBRT to us
 
157
         */
 
158
        .data
 
159
        .globl hinterface
 
160
        .globl __hinterface_start
 
161
__hinterface_start:
 
162
hinterface:
 
163
        /* HBRT interface version */
 
164
        .llong 1
 
165
 
 
166
        /* Callout pointers */
 
167
        CALLBACK_THUNK(hservice_puts)
 
168
        CALLBACK_THUNK(hservice_assert)
 
169
        CALLBACK_THUNK(hservice_set_page_execute)
 
170
        CALLBACK_THUNK(hservice_malloc)
 
171
        CALLBACK_THUNK(hservice_free)
 
172
        CALLBACK_THUNK(hservice_realloc)
 
173
        DISABLED_THUNK(hservice_send_error_log)
 
174
        CALLBACK_THUNK(hservice_scom_read)
 
175
        CALLBACK_THUNK(hservice_scom_write)
 
176
        DISABLED_THUNK(hservice_lid_load)
 
177
        DISABLED_THUNK(hservice_lid_unload)
 
178
        CALLBACK_THUNK(hservice_get_reserved_mem)
 
179
        DISABLED_THUNK(hservice_wakeup)
 
180
        CALLBACK_THUNK(hservice_nanosleep)
 
181
        DISABLED_THUNK(hservice_report_occ_failure)
 
182
        CALLBACK_THUNK(hservice_clock_gettime)
 
183
        CALLBACK_THUNK(hservice_pnor_read)
 
184
        CALLBACK_THUNK(hservice_pnor_write)
 
185
        CALLBACK_THUNK(hservice_i2c_read)
 
186
        CALLBACK_THUNK(hservice_i2c_write)
 
187
        CALLBACK_THUNK(hservice_ipmi_msg)
 
188
        CALLBACK_THUNK(hservice_memory_error)
 
189
        CALLBACK_THUNK(hservice_get_interface_capabilities)
 
190
.globl __hinterface_pad
 
191
__hinterface_pad:
 
192
        /* Reserved space for future growth */
 
193
        .space 31*8,0
 
194
.globl __hinterface_end
 
195
__hinterface_end:
 
196
        /* Eye catcher for debugging */
 
197
        .llong 0xdeadbeef
 
198