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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
|
#ifndef _IPXE_SBI_H
#define _IPXE_SBI_H
/** @file
*
* Supervisor Binary Interface (SBI)
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
/** An SBI function return value */
struct sbi_return {
/** Error status (returned in a0) */
long error;
/** Data value (returned in a1) */
long value;
};
/**
* @defgroup sbierrors SBI errors
*
* *{
*/
#define SBI_SUCCESS 0 /**< Completed successfully */
#define SBI_ERR_FAILED -1 /**< Failed */
#define SBI_ERR_NOT_SUPPORTED -2 /**< Not supported */
#define SBI_ERR_INVALID_PARAM -3 /**< Invalid parameter(s) */
#define SBI_ERR_DENIED -4 /**< Denied or not allowed */
#define SBI_ERR_INVALID_ADDRESS -5 /**< Invalid address(es) */
#define SBI_ERR_ALREADY_AVAILABLE -6 /**< Already available */
#define SBI_ERR_ALREADY_STARTED -7 /**< Already started */
#define SBI_ERR_ALREADY_STOPPED -8 /**< Already stopped */
#define SBI_ERR_NO_SHMEM -9 /**< Shared memory not available */
#define SBI_ERR_INVALID_STATE -10 /**< Invalid state */
#define SBI_ERR_BAD_RANGE -11 /**< Bad (or invalid) range */
#define SBI_ERR_TIMEOUT -12 /**< Failed due to timeout */
#define SBI_ERR_IO -13 /**< Input/output error */
/** @} */
/** Construct SBI extension ID */
#define SBI_EID( c1, c2, c3, c4 ) \
( (int) ( ( (c1) << 24 ) | ( (c2) << 16 ) | ( (c3) << 8 ) | (c4) ) )
/**
* Call supervisor with no parameters
*
* @v eid Extension ID
* @v fid Function ID
* @ret ret Return value
*/
static inline __attribute__ (( always_inline )) struct sbi_return
sbi_ecall_0 ( int eid, int fid ) {
register unsigned long a7 asm ( "a7" ) = ( ( long ) eid );
register unsigned long a6 asm ( "a6" ) = ( ( long ) fid );
register unsigned long a0 asm ( "a0" );
register unsigned long a1 asm ( "a1" );
struct sbi_return ret;
__asm__ __volatile__ ( "ecall"
: "=r" ( a0 ), "=r" ( a1 )
: "r" ( a6 ), "r" ( a7 )
: "memory" );
ret.error = a0;
ret.value = a1;
return ret;
}
/**
* Call supervisor with one parameter
*
* @v eid Extension ID
* @v fid Function ID
* @v p0 Parameter 0
* @ret ret Return value
*/
static inline __attribute__ (( always_inline )) struct sbi_return
sbi_ecall_1 ( int eid, int fid, unsigned long p0 ) {
register unsigned long a7 asm ( "a7" ) = ( ( long ) eid );
register unsigned long a6 asm ( "a6" ) = ( ( long ) fid );
register unsigned long a0 asm ( "a0" ) = p0;
register unsigned long a1 asm ( "a1" );
struct sbi_return ret;
__asm__ __volatile__ ( "ecall"
: "+r" ( a0 ), "=r" ( a1 )
: "r" ( a6 ), "r" ( a7 )
: "memory" );
ret.error = a0;
ret.value = a1;
return ret;
}
/**
* Call supervisor with two parameters
*
* @v eid Extension ID
* @v fid Function ID
* @v p0 Parameter 0
* @v p1 Parameter 1
* @ret ret Return value
*/
static inline __attribute__ (( always_inline )) struct sbi_return
sbi_ecall_2 ( int eid, int fid, unsigned long p0, unsigned long p1 ) {
register unsigned long a7 asm ( "a7" ) = ( ( long ) eid );
register unsigned long a6 asm ( "a6" ) = ( ( long ) fid );
register unsigned long a0 asm ( "a0" ) = p0;
register unsigned long a1 asm ( "a1" ) = p1;
struct sbi_return ret;
__asm__ __volatile__ ( "ecall"
: "+r" ( a0 ), "+r" ( a1 )
: "r" ( a6 ), "r" ( a7 )
: "memory" );
ret.error = a0;
ret.value = a1;
return ret;
}
/**
* Call supervisor with three parameters
*
* @v eid Extension ID
* @v fid Function ID
* @v p0 Parameter 0
* @v p1 Parameter 1
* @v p2 Parameter 2
* @ret ret Return value
*/
static inline __attribute__ (( always_inline )) struct sbi_return
sbi_ecall_3 ( int eid, int fid, unsigned long p0, unsigned long p1,
unsigned long p2 ) {
register unsigned long a7 asm ( "a7" ) = ( ( long ) eid );
register unsigned long a6 asm ( "a6" ) = ( ( long ) fid );
register unsigned long a0 asm ( "a0" ) = p0;
register unsigned long a1 asm ( "a1" ) = p1;
register unsigned long a2 asm ( "a2" ) = p2;
struct sbi_return ret;
__asm__ __volatile__ ( "ecall"
: "+r" ( a0 ), "+r" ( a1 )
: "r" ( a2 ), "r" ( a6 ), "r" ( a7 )
: "memory" );
ret.error = a0;
ret.value = a1;
return ret;
}
/**
* Call supervisor with no parameters
*
* @v fid Legacy function ID
* @ret ret Return value
*/
static inline __attribute__ (( always_inline )) long
sbi_legacy_ecall_0 ( int fid ) {
register unsigned long a7 asm ( "a7" ) = ( ( long ) fid );
register unsigned long a0 asm ( "a0" );
__asm__ __volatile__ ( "ecall"
: "=r" ( a0 )
: "r" ( a7 )
: "memory" );
return a0;
}
/**
* Call supervisor with one parameter
*
* @v fid Legacy function ID
* @v p0 Parameter 0
* @ret ret Return value
*/
static inline __attribute__ (( always_inline )) long
sbi_legacy_ecall_1 ( int fid, unsigned long p0 ) {
register unsigned long a7 asm ( "a7" ) = ( ( long ) fid );
register unsigned long a0 asm ( "a0" ) = p0;
__asm__ __volatile__ ( "ecall"
: "+r" ( a0 )
: "r" ( a7 )
: "memory" );
return a0;
}
/** Convert an SBI error code to an iPXE status code */
#define ESBI( error ) EPLATFORM ( EINFO_EPLATFORM, error )
/** Legacy extensions */
#define SBI_LEGACY_PUTCHAR 0x01 /**< Console Put Character */
#define SBI_LEGACY_GETCHAR 0x02 /**< Console Get Character */
#define SBI_LEGACY_SHUTDOWN 0x08 /**< System Shutdown */
/** Base extension */
#define SBI_BASE 0x10
#define SBI_BASE_MVENDORID 0x04 /**< Get machine vendor ID */
/** System reset extension */
#define SBI_SRST SBI_EID ( 'S', 'R', 'S', 'T' )
#define SBI_SRST_SYSTEM_RESET 0x00 /**< Reset system */
#define SBI_RESET_SHUTDOWN 0x00000000 /**< Shutdown */
#define SBI_RESET_COLD 0x00000001 /**< Cold reboot */
#define SBI_RESET_WARM 0x00000002 /**< Warm reboot */
/** Debug console extension */
#define SBI_DBCN SBI_EID ( 'D', 'B', 'C', 'N' )
#define SBI_DBCN_WRITE 0x00 /**< Console Write */
#define SBI_DBCN_READ 0x01 /**< Console Read */
#define SBI_DBCN_WRITE_BYTE 0x02 /**< Console Write Byte */
#endif /* _IPXE_SBI_H */
|