Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/powerpc/ofw/ofwcall32.S
39536 views
1
/*-
2
* Copyright (C) 2009-2011 Nathan Whitehorn
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
*/
25
26
#include <sys/syscall.h>
27
28
#include <machine/trap.h>
29
#include <machine/param.h>
30
#include <machine/spr.h>
31
#include <machine/asm.h>
32
33
#define OFWSTKSZ 4096 /* 4K Open Firmware stack */
34
35
/*
36
* Globals
37
*/
38
.data
39
GLOBAL(ofmsr)
40
.long 0, 0, 0, 0, 0 /* msr/sprg0-3 used in Open Firmware */
41
GLOBAL(rtasmsr)
42
.long 0
43
GLOBAL(openfirmware_entry)
44
.long 0 /* Open Firmware entry point */
45
GLOBAL(rtas_entry)
46
.long 0 /* RTAS entry point */
47
48
.align 4
49
ofwstk:
50
.space OFWSTKSZ
51
rtas_regsave:
52
.space 4
53
54
/*
55
* Open Firmware Entry Point. May need to enter real mode.
56
*
57
* C prototype: int ofwcall(void *callbuffer);
58
*/
59
60
ASENTRY(ofwcall)
61
mflr %r0
62
stw %r0,4(%r1)
63
64
/* Record the old MSR */
65
mfmsr %r6
66
67
/* GOT pointer in r7 */
68
bl 1f
69
1:
70
mflr %r7
71
addis %r7,%r7,(_GLOBAL_OFFSET_TABLE_-1b)@ha
72
addi %r7,%r7,(_GLOBAL_OFFSET_TABLE_-1b)@l
73
74
/* read client interface handler */
75
lwz %r4,openfirmware_entry@got(%r7)
76
lwz %r4,0(%r4)
77
78
/*
79
* Set the MSR to the OF value. This has the side effect of disabling
80
* exceptions, which prevents preemption later.
81
*/
82
83
lwz %r5,ofmsr@got(%r7)
84
lwz %r5,0(%r5)
85
mtmsr %r5
86
isync
87
88
/*
89
* Set up OF stack. This needs to be potentially accessible in real mode
90
* The pointer to the current kernel stack is placed at the very
91
* top of the stack along with the old MSR so we can get them back
92
* later.
93
*/
94
mr %r5,%r1
95
lwz %r1,ofwstk@got(%r7)
96
addi %r1,%r1,(OFWSTKSZ-32)
97
stw %r5,20(%r1) /* Save real stack pointer */
98
stw %r2,24(%r1) /* Save curthread */
99
stw %r6,28(%r1) /* Save old MSR */
100
li %r5,0
101
stw %r5,4(%r1)
102
stw %r5,0(%r1)
103
104
/* Finally, branch to OF */
105
mtctr %r4
106
bctrl
107
108
/* Reload stack pointer and MSR from the OFW stack */
109
lwz %r6,28(%r1)
110
lwz %r2,24(%r1)
111
lwz %r1,20(%r1)
112
113
/* Now set the real MSR */
114
mtmsr %r6
115
isync
116
117
/* Return */
118
lwz %r0,4(%r1)
119
mtlr %r0
120
blr
121
ASEND(ofwcall)
122
123
/*
124
* RTAS Entry Point. Similar to the OF one, but simpler (no separate stack)
125
*
126
* C prototype: int rtascall(void *callbuffer, void *rtas_privdat);
127
*/
128
129
ASENTRY(rtascall)
130
mflr %r0
131
stw %r0,4(%r1)
132
133
/* GOT pointer in r7 */
134
bl 1f
135
1:
136
mflr %r7
137
addis %r7,%r7,(_GLOBAL_OFFSET_TABLE_-1b)@ha
138
addi %r7,%r7,(_GLOBAL_OFFSET_TABLE_-1b)@l
139
140
/* Record the old MSR to real-mode-accessible area */
141
mfmsr %r0
142
lwz %r5,rtas_regsave@got(%r7)
143
stw %r0,0(%r5)
144
145
/* read client interface handler */
146
lwz %r5,rtas_entry@got(%r7)
147
lwz %r5,0(%r5)
148
149
/* Set the MSR to the RTAS value */
150
lwz %r6,rtasmsr@got(%r7)
151
lwz %r6,0(%r6)
152
mtmsr %r6
153
isync
154
155
/* Branch to RTAS */
156
mtctr %r5
157
bctrl
158
159
/* GOT pointer in r7 */
160
bl 1f
161
1:
162
mflr %r7
163
addis %r7,%r7,(_GLOBAL_OFFSET_TABLE_-1b)@ha
164
addi %r7,%r7,(_GLOBAL_OFFSET_TABLE_-1b)@l
165
166
/* Now set the MSR back */
167
lwz %r6,rtas_regsave@got(%r7)
168
lwz %r6,0(%r6)
169
mtmsr %r6
170
isync
171
172
/* And return */
173
lwz %r0,4(%r1)
174
mtlr %r0
175
blr
176
ASEND(rtascall)
177
178