|
@@ -1,243 +0,0 @@
|
1
|
|
-/* Callout/callback interface for Etherboot
|
2
|
|
- *
|
3
|
|
- * This file provides the mechanisms for making calls from Etherboot
|
4
|
|
- * to external programs and vice-versa.
|
5
|
|
- *
|
6
|
|
- * Initial version by Michael Brown <mbrown@fensystems.co.uk>, January 2004.
|
7
|
|
- *
|
8
|
|
- * $Id$
|
9
|
|
- */
|
10
|
|
-
|
11
|
|
-#ifndef CALLBACKS_ARCH_H
|
12
|
|
-#define CALLBACKS_ARCH_H
|
13
|
|
-
|
14
|
|
-/* Skip the definitions that won't make sense to the assembler */
|
15
|
|
-#ifndef ASSEMBLY
|
16
|
|
-
|
17
|
|
-/* Struct to hold general-purpose register values. PUSHAL and POPAL
|
18
|
|
- * can work directly with this structure; do not change the order of
|
19
|
|
- * registers.
|
20
|
|
- */
|
21
|
|
-typedef struct {
|
22
|
|
- union {
|
23
|
|
- uint16_t di;
|
24
|
|
- uint32_t edi;
|
25
|
|
- };
|
26
|
|
- union {
|
27
|
|
- uint16_t si;
|
28
|
|
- uint32_t esi;
|
29
|
|
- };
|
30
|
|
- union {
|
31
|
|
- uint16_t bp;
|
32
|
|
- uint32_t ebp;
|
33
|
|
- };
|
34
|
|
- union {
|
35
|
|
- uint16_t sp;
|
36
|
|
- uint32_t esp;
|
37
|
|
- };
|
38
|
|
- union {
|
39
|
|
- struct {
|
40
|
|
- uint8_t bl;
|
41
|
|
- uint8_t bh;
|
42
|
|
- } PACKED;
|
43
|
|
- uint16_t bx;
|
44
|
|
- uint32_t ebx;
|
45
|
|
- };
|
46
|
|
- union {
|
47
|
|
- struct {
|
48
|
|
- uint8_t dl;
|
49
|
|
- uint8_t dh;
|
50
|
|
- } PACKED;
|
51
|
|
- uint16_t dx;
|
52
|
|
- uint32_t edx;
|
53
|
|
- };
|
54
|
|
- union {
|
55
|
|
- struct {
|
56
|
|
- uint8_t cl;
|
57
|
|
- uint8_t ch;
|
58
|
|
- } PACKED;
|
59
|
|
- uint16_t cx;
|
60
|
|
- uint32_t ecx;
|
61
|
|
- };
|
62
|
|
- union {
|
63
|
|
- struct {
|
64
|
|
- uint8_t al;
|
65
|
|
- uint8_t ah;
|
66
|
|
- } PACKED;
|
67
|
|
- uint16_t ax;
|
68
|
|
- uint32_t eax;
|
69
|
|
- };
|
70
|
|
-} regs_t;
|
71
|
|
-
|
72
|
|
-/* Struct to hold segment register values. Don't change the order;
|
73
|
|
- * many bits of assembly code rely on it.
|
74
|
|
- */
|
75
|
|
-typedef struct {
|
76
|
|
- uint16_t cs;
|
77
|
|
- uint16_t ss;
|
78
|
|
- uint16_t ds;
|
79
|
|
- uint16_t es;
|
80
|
|
- uint16_t fs;
|
81
|
|
- uint16_t gs;
|
82
|
|
-} PACKED seg_regs_t;
|
83
|
|
-
|
84
|
|
-/* Struct for a GDT descriptor */
|
85
|
|
-typedef struct {
|
86
|
|
- uint16_t limit;
|
87
|
|
- uint32_t address;
|
88
|
|
- uint16_t padding;
|
89
|
|
-} PACKED gdt_descriptor_t;
|
90
|
|
-
|
91
|
|
-/* Struct for a GDT entry. Use GDT_SEGMENT() to fill it in.
|
92
|
|
- */
|
93
|
|
-typedef struct {
|
94
|
|
- uint16_t limit_0_15;
|
95
|
|
- uint16_t base_0_15;
|
96
|
|
- uint8_t base_16_23;
|
97
|
|
- uint8_t accessed__type__sflag__dpl__present;
|
98
|
|
- uint8_t limit_16_19__avl__size__granularity;
|
99
|
|
- uint8_t base_24_31;
|
100
|
|
-} PACKED gdt_segment_t;
|
101
|
|
-
|
102
|
|
-#define GDT_SEGMENT(base,limit,type,sflag,dpl,avl,size,granularity) \
|
103
|
|
- ( (gdt_segment_t) { \
|
104
|
|
- ( (limit) & 0xffff ), \
|
105
|
|
- ( (base) & 0xffff ), \
|
106
|
|
- ( ( (base) >> 16 ) & 0xff ), \
|
107
|
|
- ( ( 1 << 0 ) | ( (type) << 1 ) | \
|
108
|
|
- ( (sflag) << 4 ) | ( (dpl) << 5 ) | ( 1 << 7 ) ), \
|
109
|
|
- ( ( (limit) >> 16 ) | \
|
110
|
|
- ( (avl) << 4 ) | ( (size) << 5 ) | ( (granularity) << 7 ) ),\
|
111
|
|
- ( (base) >> 24 ) \
|
112
|
|
- } )
|
113
|
|
-#define GDT_SEGMENT_BASE(gdt_segment) \
|
114
|
|
- ( (gdt_segment)->base_0_15 | \
|
115
|
|
- (gdt_segment)->base_16_23 << 16 | \
|
116
|
|
- (gdt_segment)->base_24_31 << 24 )
|
117
|
|
-#define GDT_SEGMENT_LIMIT(gdt_segment) \
|
118
|
|
- ( (gdt_segment)->limit_0_15 | \
|
119
|
|
- ( ( (gdt_segment)->limit_16_19__avl__size__granularity \
|
120
|
|
- & 0xf ) << 16 ) )
|
121
|
|
-#define GDT_SEGMENT_GRANULARITY(gdt_segment) \
|
122
|
|
- ( ( (gdt_segment)->limit_16_19__avl__size__granularity \
|
123
|
|
- & 0x80 ) >> 7 )
|
124
|
|
-#define GDT_SEGMENT_TYPE(gdt_segment) \
|
125
|
|
- ( ( (gdt_segment)->accessed__type__sflag__dpl__present & 0x0e ) >> 1 )
|
126
|
|
-#define GDT_SEGMENT_SIZE(gdt_segment) \
|
127
|
|
- ( ( (gdt_segment)->limit_16_19__avl__size__granularity \
|
128
|
|
- & 0x60 ) >> 5 )
|
129
|
|
-
|
130
|
|
-#define GDT_TYPE_DATA (0x0)
|
131
|
|
-#define GDT_TYPE_STACK (0x2)
|
132
|
|
-#define GDT_TYPE_WRITEABLE (0x1)
|
133
|
|
-#define GDT_TYPE_CODE (0x6)
|
134
|
|
-#define GDT_TYPE_EXEC_ONLY_CODE (0x4)
|
135
|
|
-#define GDT_TYPE_CONFORMING (0x1)
|
136
|
|
-#define GDT_SFLAG_SYSTEM (0)
|
137
|
|
-#define GDT_SFLAG_NORMAL (1)
|
138
|
|
-#define GDT_AVL_NORMAL (0)
|
139
|
|
-#define GDT_SIZE_16BIT (0x0)
|
140
|
|
-#define GDT_SIZE_32BIT (0x2)
|
141
|
|
-#define GDT_SIZE_64BIT (0x1)
|
142
|
|
-#define GDT_SIZE_UNKNOWN (0x3)
|
143
|
|
-#define GDT_GRANULARITY_SMALL (0)
|
144
|
|
-#define GDT_GRANULARITY_LARGE (1)
|
145
|
|
-#define GDT_SEGMENT_NORMAL(base,limit,type,size,granularity) \
|
146
|
|
- GDT_SEGMENT ( base, limit, type, \
|
147
|
|
- GDT_SFLAG_NORMAL, 0, GDT_AVL_NORMAL, \
|
148
|
|
- size, granularity )
|
149
|
|
-
|
150
|
|
-/* Protected mode code segment */
|
151
|
|
-#define GDT_SEGMENT_PMCS(base) GDT_SEGMENT_NORMAL ( \
|
152
|
|
- base, 0xfffff, GDT_TYPE_CODE | GDT_TYPE_CONFORMING, \
|
153
|
|
- GDT_SIZE_32BIT, GDT_GRANULARITY_LARGE )
|
154
|
|
-#define GDT_SEGMENT_PMCS_PHYS GDT_SEGMENT_PMCS(0)
|
155
|
|
-/* Protected mode data segment */
|
156
|
|
-#define GDT_SEGMENT_PMDS(base) GDT_SEGMENT_NORMAL ( \
|
157
|
|
- base, 0xfffff, GDT_TYPE_DATA | GDT_TYPE_WRITEABLE, \
|
158
|
|
- GDT_SIZE_32BIT, GDT_GRANULARITY_LARGE )
|
159
|
|
-#define GDT_SEGMENT_PMDS_PHYS GDT_SEGMENT_PMDS(0)
|
160
|
|
-/* Real mode code segment */
|
161
|
|
-/* Not sure if there's any reason to use GDT_TYPE_EXEC_ONLY_CODE
|
162
|
|
- * instead of just GDT_TYPE_CODE, but that's what our old GDT did and
|
163
|
|
- * it worked, so I'm not changing it.
|
164
|
|
- */
|
165
|
|
-#define GDT_SEGMENT_RMCS(base) GDT_SEGMENT_NORMAL ( \
|
166
|
|
- base, 0xffff, GDT_TYPE_EXEC_ONLY_CODE | GDT_TYPE_CONFORMING, \
|
167
|
|
- GDT_SIZE_16BIT, GDT_GRANULARITY_SMALL )
|
168
|
|
-/* Real mode data segment */
|
169
|
|
-#define GDT_SEGMENT_RMDS(base) GDT_SEGMENT_NORMAL ( \
|
170
|
|
- base, 0xffff, GDT_TYPE_DATA | GDT_TYPE_WRITEABLE, \
|
171
|
|
- GDT_SIZE_16BIT, GDT_GRANULARITY_SMALL )
|
172
|
|
-/* Long mode code segment */
|
173
|
|
-#define GDT_SEGMENT_LMCS(base) GDT_SEGMENT_NORMAL ( \
|
174
|
|
- base, 0xfffff, GDT_TYPE_CODE | GDT_TYPE_CONFORMING, \
|
175
|
|
- GDT_SIZE_64BIT, GDT_GRANULARITY_LARGE )
|
176
|
|
-#define GDT_SEGMENT_LMCS_PHYS GDT_SEGMENT_LMCS(0)
|
177
|
|
-/* Long mode data segment */
|
178
|
|
-/* AFIACT, GDT_SIZE_64BIT applies only to code segments */
|
179
|
|
-#define GDT_SEGMENT_LMDS(base) GDT_SEGMENT_NORMAL ( \
|
180
|
|
- base, 0xfffff, GDT_TYPE_DATA | GDT_TYPE_WRITEABLE, \
|
181
|
|
- GDT_SIZE_32BIT, GDT_GRANULARITY_LARGE )
|
182
|
|
-#define GDT_SEGMENT_LMDS_PHYS GDT_SEGMENT_LMDS(0)
|
183
|
|
-
|
184
|
|
-/* Template for creating GDT structures (including segment register
|
185
|
|
- * lists), suitable for passing as parameters to external_call().
|
186
|
|
- */
|
187
|
|
-#define GDT_STRUCT_t(num_segments) \
|
188
|
|
- struct { \
|
189
|
|
- gdt_descriptor_t descriptor; \
|
190
|
|
- gdt_segment_t segments[num_segments]; \
|
191
|
|
- } PACKED
|
192
|
|
-/* And utility function for filling it in */
|
193
|
|
-#define GDT_ADJUST(structure) { \
|
194
|
|
- (structure)->descriptor.address = \
|
195
|
|
- virt_to_phys(&((structure)->descriptor.limit)); \
|
196
|
|
- (structure)->descriptor.limit = \
|
197
|
|
- sizeof((structure)->segments) + 8 - 1; \
|
198
|
|
- (structure)->descriptor.padding = 0; \
|
199
|
|
-}
|
200
|
|
-
|
201
|
|
-/* Data passed in to in_call() by assembly wrapper.
|
202
|
|
- */
|
203
|
|
-typedef struct {
|
204
|
|
- regs_t regs;
|
205
|
|
- seg_regs_t seg_regs;
|
206
|
|
- gdt_descriptor_t gdt_desc;
|
207
|
|
- uint32_t flags;
|
208
|
|
- struct {
|
209
|
|
- uint32_t offset;
|
210
|
|
- uint32_t segment;
|
211
|
|
- } ret_addr;
|
212
|
|
-} PACKED i386_pm_in_call_data_t;
|
213
|
|
-
|
214
|
|
-typedef struct {
|
215
|
|
- seg_regs_t seg_regs;
|
216
|
|
- union {
|
217
|
|
- uint16_t pad;
|
218
|
|
- uint16_t prefix_sp;
|
219
|
|
- };
|
220
|
|
- uint16_t flags;
|
221
|
|
- struct {
|
222
|
|
- uint16_t offset;
|
223
|
|
- uint16_t segment;
|
224
|
|
- } ret_addr;
|
225
|
|
- uint32_t orig_opcode;
|
226
|
|
-} PACKED i386_rm_in_call_data_t;
|
227
|
|
-
|
228
|
|
-typedef struct {
|
229
|
|
- i386_pm_in_call_data_t *pm;
|
230
|
|
- i386_rm_in_call_data_t *rm;
|
231
|
|
-} i386_in_call_data_t;
|
232
|
|
-#define in_call_data_t i386_in_call_data_t
|
233
|
|
-
|
234
|
|
-/* Function prototypes
|
235
|
|
- */
|
236
|
|
-extern int install_rm_callback_interface ( void *address, size_t available );
|
237
|
|
-
|
238
|
|
-#endif /* ASSEMBLY */
|
239
|
|
-
|
240
|
|
-#define RM_IN_CALL (0)
|
241
|
|
-#define RM_IN_CALL_FAR (2)
|
242
|
|
-
|
243
|
|
-#endif /* CALLBACKS_ARCH_H */
|