[build] Remove PACKED macro
[people/stefanha/gpxe.git] / src / arch / i386 / include / registers.h
1 #ifndef REGISTERS_H
2 #define REGISTERS_H
3
4 /** @file
5  *
6  * i386 registers.
7  *
8  * This file defines data structures that allow easy access to i386
9  * register dumps.
10  *
11  */
12
13 FILE_LICENCE ( GPL2_OR_LATER );
14
15 #include <stdint.h>
16
17 /**
18  * A 16-bit general register.
19  *
20  * This type encapsulates a 16-bit register such as %ax, %bx, %cx,
21  * %dx, %si, %di, %bp or %sp.
22  *
23  */
24 typedef union {
25         struct {
26                 union {
27                         uint8_t l;
28                         uint8_t byte;
29                 };
30                 uint8_t h;
31         } __attribute__ (( packed ));
32         uint16_t word;
33 } __attribute__ (( packed )) reg16_t;
34
35 /**
36  * A 32-bit general register.
37  *
38  * This type encapsulates a 32-bit register such as %eax, %ebx, %ecx,
39  * %edx, %esi, %edi, %ebp or %esp.
40  *
41  */
42 typedef union {
43         struct {
44                 union {
45                         uint8_t l;
46                         uint8_t byte;
47                 };
48                 uint8_t h;
49         } __attribute__ (( packed ));
50         uint16_t word;
51         uint32_t dword;
52 } __attribute__ (( packed )) reg32_t;
53
54 /**
55  * A 32-bit general register dump.
56  *
57  * This is the data structure that is created on the stack by the @c
58  * pushal instruction, and can be read back using the @c popal
59  * instruction.
60  *
61  */
62 struct i386_regs {
63         union {
64                 uint16_t di;
65                 uint32_t edi;
66         };
67         union {
68                 uint16_t si;
69                 uint32_t esi;
70         };
71         union {
72                 uint16_t bp;
73                 uint32_t ebp;
74         };
75         union {
76                 uint16_t sp;
77                 uint32_t esp;
78         };
79         union {
80                 struct {
81                         uint8_t bl;
82                         uint8_t bh;
83                 } __attribute__ (( packed ));
84                 uint16_t bx;
85                 uint32_t ebx;
86         };
87         union {
88                 struct {
89                         uint8_t dl;
90                         uint8_t dh;
91                 } __attribute__ (( packed ));
92                 uint16_t dx;
93                 uint32_t edx;
94         };
95         union {
96                 struct {
97                         uint8_t cl;
98                         uint8_t ch;
99                 } __attribute__ (( packed ));
100                 uint16_t cx;
101                 uint32_t ecx;
102         };
103         union {
104                 struct {
105                         uint8_t al;
106                         uint8_t ah;
107                 } __attribute__ (( packed ));
108                 uint16_t ax;
109                 uint32_t eax;
110         };
111 } __attribute__ (( packed ));
112
113 /**
114  * A segment register dump.
115  *
116  * The i386 has no equivalent of the @c pushal or @c popal
117  * instructions for the segment registers.  We adopt the convention of
118  * always using the sequences
119  *
120  * @code
121  *
122  *   pushw %gs ; pushw %fs ; pushw %es ; pushw %ds ; pushw %ss ; pushw %cs
123  *
124  * @endcode
125  *
126  * and
127  *
128  * @code
129  *
130  *   addw $4, %sp ; popw %ds ; popw %es ; popw %fs ; popw %gs
131  *
132  * @endcode
133  *
134  * This is the data structure that is created and read back by these
135  * instruction sequences.
136  *
137  */
138 struct i386_seg_regs {
139         uint16_t cs;
140         uint16_t ss;
141         uint16_t ds;
142         uint16_t es;
143         uint16_t fs;
144         uint16_t gs;
145 } __attribute__ (( packed ));
146
147 /**
148  * A full register dump.
149  *
150  * This data structure is created by the instructions
151  *
152  * @code
153  *
154  *   pushfl
155  *   pushal
156  *   pushw %gs ; pushw %fs ; pushw %es ; pushw %ds ; pushw %ss ; pushw %cs
157  *
158  * @endcode
159  *
160  * and can be read back using the instructions
161  *
162  * @code
163  *
164  *   addw $4, %sp ; popw %ds ; popw %es ; popw %fs ; popw %gs
165  *   popal
166  *   popfl
167  *
168  * @endcode
169  *
170  * prot_call() and kir_call() create this data structure on the stack
171  * and pass in a pointer to this structure.
172  *
173  */
174 struct i386_all_regs {
175         struct i386_seg_regs segs;
176         struct i386_regs regs;
177         uint32_t flags;
178 } __attribute__ (( packed ));
179
180 /* Flags */
181 #define CF ( 1 <<  0 )
182 #define PF ( 1 <<  2 )
183 #define AF ( 1 <<  4 )
184 #define ZF ( 1 <<  6 )
185 #define SF ( 1 <<  7 )
186 #define OF ( 1 << 11 )
187
188 /* Segment:offset structure.  Note that the order within the structure
189  * is offset:segment.
190  */
191 struct segoff {
192         uint16_t offset;
193         uint16_t segment;
194 } __attribute__ (( packed ));
195
196 typedef struct segoff segoff_t;
197
198 #endif /* REGISTERS_H */