666532389061979293f61356285cc020e5a6768a
[people/xl0/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 #include "compiler.h" /* for doxygen */
14 #include "stdint.h"
15
16 /**
17  * A 16-bit general register.
18  *
19  * This type encapsulates a 16-bit register such as %ax, %bx, %cx,
20  * %dx, %si, %di, %bp or %sp.
21  *
22  */
23 typedef union {
24         struct {
25                 union {
26                         uint8_t l;
27                         uint8_t byte;
28                 };
29                 uint8_t h;
30         } PACKED;
31         uint16_t word;
32 } PACKED reg16_t;
33
34 /**
35  * A 32-bit general register.
36  *
37  * This type encapsulates a 32-bit register such as %eax, %ebx, %ecx,
38  * %edx, %esi, %edi, %ebp or %esp.
39  *
40  */
41 typedef union {
42         struct {
43                 union {
44                         uint8_t l;
45                         uint8_t byte;
46                 };
47                 uint8_t h;
48         } PACKED;
49         uint16_t word;
50         uint32_t dword;
51 } PACKED reg32_t;
52
53 /**
54  * A 32-bit general register dump.
55  *
56  * This is the data structure that is created on the stack by the @c
57  * pushal instruction, and can be read back using the @c popal
58  * instruction.
59  *
60  */
61 struct i386_regs {
62         union {
63                 uint16_t di;
64                 uint32_t edi;
65         };
66         union {
67                 uint16_t si;
68                 uint32_t esi;
69         };
70         union {
71                 uint16_t bp;
72                 uint32_t ebp;
73         };
74         union {
75                 uint16_t sp;
76                 uint32_t esp;
77         };
78         union {
79                 struct {
80                         uint8_t bl;
81                         uint8_t bh;
82                 } PACKED;
83                 uint16_t bx;
84                 uint32_t ebx;
85         };
86         union {
87                 struct {
88                         uint8_t dl;
89                         uint8_t dh;
90                 } PACKED;
91                 uint16_t dx;
92                 uint32_t edx;
93         };
94         union {
95                 struct {
96                         uint8_t cl;
97                         uint8_t ch;
98                 } PACKED;
99                 uint16_t cx;
100                 uint32_t ecx;
101         };
102         union {
103                 struct {
104                         uint8_t al;
105                         uint8_t ah;
106                 } PACKED;
107                 uint16_t ax;
108                 uint32_t eax;
109         };
110 } PACKED;
111
112 /**
113  * A segment register dump.
114  *
115  * The i386 has no equivalent of the @c pushal or @c popal
116  * instructions for the segment registers.  We adopt the convention of
117  * always using the sequences
118  *
119  * @code
120  *
121  *   pushw %gs ; pushw %fs ; pushw %es ; pushw %ds ; pushw %ss ; pushw %cs
122  *
123  * @endcode
124  *
125  * and
126  *
127  * @code
128  *
129  *   addw $4, %sp ; popw %ds ; popw %es ; popw %fs ; popw %gs
130  *
131  * @endcode
132  *
133  * This is the data structure that is created and read back by these
134  * instruction sequences.
135  *
136  */
137 struct i386_seg_regs {
138         uint16_t cs;
139         uint16_t ss;
140         uint16_t ds;
141         uint16_t es;
142         uint16_t fs;
143         uint16_t gs;
144 } PACKED;
145
146 /**
147  * A full register dump.
148  *
149  * This data structure is created by the instructions
150  *
151  * @code
152  *
153  *   pushfl
154  *   pushal
155  *   pushw %gs ; pushw %fs ; pushw %es ; pushw %ds ; pushw %ss ; pushw %cs
156  *
157  * @endcode
158  *
159  * and can be read back using the instructions
160  *
161  * @code
162  *
163  *   addw $4, %sp ; popw %ds ; popw %es ; popw %fs ; popw %gs
164  *   popal
165  *   popfl
166  *
167  * @endcode
168  *
169  * prot_call() and kir_call() create this data structure on the stack
170  * and pass in a pointer to this structure.
171  *
172  */
173 struct i386_all_regs {
174         struct i386_seg_regs segs;
175         struct i386_regs regs;
176         uint32_t flags;
177 } PACKED;
178
179 #endif /* REGISTERS_H */