1 |
27 |
unneback |
#ifndef CYGONCE_HAL_I386_STUB_H
|
2 |
|
|
#define CYGONCE_HAL_I386_STUB_H
|
3 |
|
|
//==========================================================================
|
4 |
|
|
//
|
5 |
|
|
// i386_stub.h
|
6 |
|
|
//
|
7 |
|
|
// i386/PC GDB stub support
|
8 |
|
|
//
|
9 |
|
|
//==========================================================================
|
10 |
|
|
//####ECOSGPLCOPYRIGHTBEGIN####
|
11 |
|
|
// -------------------------------------------
|
12 |
|
|
// This file is part of eCos, the Embedded Configurable Operating System.
|
13 |
|
|
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
|
14 |
|
|
//
|
15 |
|
|
// eCos is free software; you can redistribute it and/or modify it under
|
16 |
|
|
// the terms of the GNU General Public License as published by the Free
|
17 |
|
|
// Software Foundation; either version 2 or (at your option) any later version.
|
18 |
|
|
//
|
19 |
|
|
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
|
20 |
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
21 |
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
22 |
|
|
// for more details.
|
23 |
|
|
//
|
24 |
|
|
// You should have received a copy of the GNU General Public License along
|
25 |
|
|
// with eCos; if not, write to the Free Software Foundation, Inc.,
|
26 |
|
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
27 |
|
|
//
|
28 |
|
|
// As a special exception, if other files instantiate templates or use macros
|
29 |
|
|
// or inline functions from this file, or you compile this file and link it
|
30 |
|
|
// with other works to produce a work based on this file, this file does not
|
31 |
|
|
// by itself cause the resulting work to be covered by the GNU General Public
|
32 |
|
|
// License. However the source code for this file must still be made available
|
33 |
|
|
// in accordance with section (3) of the GNU General Public License.
|
34 |
|
|
//
|
35 |
|
|
// This exception does not invalidate any other reasons why a work based on
|
36 |
|
|
// this file might be covered by the GNU General Public License.
|
37 |
|
|
//
|
38 |
|
|
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
|
39 |
|
|
// at http://sources.redhat.com/ecos/ecos-license/
|
40 |
|
|
// -------------------------------------------
|
41 |
|
|
//####ECOSGPLCOPYRIGHTEND####
|
42 |
|
|
//==========================================================================
|
43 |
|
|
//#####DESCRIPTIONBEGIN####
|
44 |
|
|
//
|
45 |
|
|
// Author(s): pjo
|
46 |
|
|
// Contributors: pjo, nickg
|
47 |
|
|
// Date: 1999-10-15
|
48 |
|
|
// Purpose: i386/PC GDB stub support
|
49 |
|
|
// Description: Definitions for the GDB stubs. Most of this comes from
|
50 |
|
|
// the original libstub code.
|
51 |
|
|
//
|
52 |
|
|
// Usage:
|
53 |
|
|
// #include <cyg/hal/plf_intr.h>
|
54 |
|
|
// ...
|
55 |
|
|
//
|
56 |
|
|
//####DESCRIPTIONEND####
|
57 |
|
|
//
|
58 |
|
|
//==========================================================================
|
59 |
|
|
|
60 |
|
|
|
61 |
|
|
#ifndef CYGHWR_HAL_I386_FPU
|
62 |
|
|
#define NUMREGS 16
|
63 |
|
|
#else
|
64 |
|
|
#ifdef CYGHWR_HAL_I386_PENTIUM_SSE
|
65 |
|
|
#define NUMREGS 41
|
66 |
|
|
#else
|
67 |
|
|
#define NUMREGS 32
|
68 |
|
|
#endif
|
69 |
|
|
#endif
|
70 |
|
|
|
71 |
|
|
// Size of a given register.
|
72 |
|
|
#define REGSIZE(X) (((X) >= REG_FST0 && (X) <= REG_FST7) ? 10 : \
|
73 |
|
|
(((X) >= REG_MMX0 && (X) <= REG_MMX7) ? 10 : \
|
74 |
|
|
(((X) == REG_GDT || (X) == REG_IDT) ? 6 : \
|
75 |
|
|
(((X) == REG_MSR || (X) == REG_LDT || (X) == REG_TR) ? 8 : \
|
76 |
|
|
(((X) >= REG_XMM0 && (X) <= REG_XMM7) ? 16 : 4)))))
|
77 |
|
|
|
78 |
|
|
enum regnames
|
79 |
|
|
{
|
80 |
|
|
// General regs (0 - 15)
|
81 |
|
|
EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
|
82 |
|
|
PC /* also known as eip */,
|
83 |
|
|
PS /* also known as eflags */,
|
84 |
|
|
CS, SS, DS, ES, FS, GS,
|
85 |
|
|
|
86 |
|
|
// FPU regs. (16 - 31)
|
87 |
|
|
REG_FST0, REG_FST1, REG_FST2, REG_FST3,
|
88 |
|
|
REG_FST4, REG_FST5, REG_FST6, REG_FST7,
|
89 |
|
|
REG_FCTRL, REG_FSTAT, REG_FTAG,
|
90 |
|
|
REG_FISEG, REG_FIOFF,
|
91 |
|
|
REG_FOSEG, REG_FOOFF,
|
92 |
|
|
REG_FOP,
|
93 |
|
|
|
94 |
|
|
// SSE regs (32 - 40)
|
95 |
|
|
REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3,
|
96 |
|
|
REG_XMM4, REG_XMM5, REG_XMM6, REG_XMM7,
|
97 |
|
|
REG_MXCSR,
|
98 |
|
|
|
99 |
|
|
// Registers below this point are _not_ part of the g/G packet
|
100 |
|
|
// so they play no part in defining NUMREGS. GDB accesses these
|
101 |
|
|
// individually with p/P packets.
|
102 |
|
|
|
103 |
|
|
// MMX regs (41 - 48)
|
104 |
|
|
// These are here as placeholders for register numbering purposes.
|
105 |
|
|
// GDB never asks for these directly as their values are stored
|
106 |
|
|
// in FSTn registers.
|
107 |
|
|
REG_MMX0, REG_MMX1, REG_MMX2, REG_MMX3,
|
108 |
|
|
REG_MMX4, REG_MMX5, REG_MMX6, REG_MMX7,
|
109 |
|
|
|
110 |
|
|
// Misc pentium regs (49 - 56)
|
111 |
|
|
REG_CR0, REG_CR2, REG_CR3, REG_CR4,
|
112 |
|
|
REG_GDT, REG_IDT, REG_LDT, REG_TR,
|
113 |
|
|
|
114 |
|
|
// Pseudo reg used by gdb to access other regs (57)
|
115 |
|
|
REG_MSR
|
116 |
|
|
};
|
117 |
|
|
|
118 |
|
|
typedef enum regnames regnames_t ;
|
119 |
|
|
typedef unsigned long target_register_t ;
|
120 |
|
|
|
121 |
|
|
typedef struct
|
122 |
|
|
{
|
123 |
|
|
target_register_t eax;
|
124 |
|
|
target_register_t ecx;
|
125 |
|
|
target_register_t edx;
|
126 |
|
|
target_register_t ebx;
|
127 |
|
|
target_register_t esp;
|
128 |
|
|
target_register_t ebp;
|
129 |
|
|
target_register_t esi;
|
130 |
|
|
target_register_t edi;
|
131 |
|
|
target_register_t pc;
|
132 |
|
|
target_register_t ps;
|
133 |
|
|
target_register_t cs;
|
134 |
|
|
target_register_t ss;
|
135 |
|
|
target_register_t ds;
|
136 |
|
|
target_register_t es;
|
137 |
|
|
target_register_t fs;
|
138 |
|
|
target_register_t gs;
|
139 |
|
|
#ifdef CYGHWR_HAL_I386_FPU
|
140 |
|
|
target_register_t fcw;
|
141 |
|
|
target_register_t fsw;
|
142 |
|
|
target_register_t ftw;
|
143 |
|
|
target_register_t ipoff;
|
144 |
|
|
target_register_t cssel;
|
145 |
|
|
target_register_t dataoff;
|
146 |
|
|
target_register_t opsel;
|
147 |
|
|
unsigned char st0[10];
|
148 |
|
|
unsigned char st1[10];
|
149 |
|
|
unsigned char st2[10];
|
150 |
|
|
unsigned char st3[10];
|
151 |
|
|
unsigned char st4[10];
|
152 |
|
|
unsigned char st5[10];
|
153 |
|
|
unsigned char st6[10];
|
154 |
|
|
unsigned char st7[10];
|
155 |
|
|
#endif
|
156 |
|
|
#ifdef CYGHWR_HAL_I386_PENTIUM_SSE
|
157 |
|
|
unsigned char xmm0[16];
|
158 |
|
|
unsigned char xmm1[16];
|
159 |
|
|
unsigned char xmm2[16];
|
160 |
|
|
unsigned char xmm3[16];
|
161 |
|
|
unsigned char xmm4[16];
|
162 |
|
|
unsigned char xmm5[16];
|
163 |
|
|
unsigned char xmm6[16];
|
164 |
|
|
unsigned char xmm7[16];
|
165 |
|
|
target_register_t mxcsr;
|
166 |
|
|
#endif
|
167 |
|
|
#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS
|
168 |
|
|
target_register_t cr0;
|
169 |
|
|
target_register_t cr2;
|
170 |
|
|
target_register_t cr3;
|
171 |
|
|
target_register_t cr4;
|
172 |
|
|
|
173 |
|
|
unsigned char gdtr[6];
|
174 |
|
|
unsigned char idtr[6];
|
175 |
|
|
target_register_t ldt;
|
176 |
|
|
target_register_t tr;
|
177 |
|
|
#endif
|
178 |
|
|
} GDB_SavedRegisters;
|
179 |
|
|
|
180 |
|
|
#define HAL_STUB_REGISTERS_SIZE \
|
181 |
|
|
((sizeof(GDB_SavedRegisters) + sizeof(target_register_t) - 1) / sizeof(target_register_t))
|
182 |
|
|
|
183 |
|
|
#define PS_C 0x00000001
|
184 |
|
|
#define PS_Z 0x00000040
|
185 |
|
|
#define PS_V 0x00000080
|
186 |
|
|
#define PS_T 0x00000100
|
187 |
|
|
|
188 |
|
|
#define SP (ESP)
|
189 |
|
|
#define EIP (PC)
|
190 |
|
|
|
191 |
|
|
// We have to rewind the PC only in case of a breakpoint
|
192 |
|
|
// set by a user interrupt (ie: a Ctrl-C)
|
193 |
|
|
|
194 |
|
|
// There should be another way to do it
|
195 |
|
|
|
196 |
|
|
#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
|
197 |
|
|
#define HAL_STUB_PLATFORM_STUBS_FIXUP() \
|
198 |
|
|
CYG_MACRO_START \
|
199 |
|
|
if (break_buffer.targetAddr==get_register(PC)-1) \
|
200 |
|
|
put_register(PC, get_register(PC) - 1); \
|
201 |
|
|
CYG_MACRO_END
|
202 |
|
|
#endif //CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
|
203 |
|
|
|
204 |
|
|
// I386 stub has special needs for register handling, so special
|
205 |
|
|
// put_register and get_register are provided.
|
206 |
|
|
#define CYGARC_STUB_REGISTER_ACCESS_DEFINED 1
|
207 |
|
|
|
208 |
|
|
// The x86 has float (and other) registers that are larger than it can
|
209 |
|
|
// hold in a target_register_t.
|
210 |
|
|
#define TARGET_HAS_LARGE_REGISTERS
|
211 |
|
|
|
212 |
|
|
#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS
|
213 |
|
|
// Handle arch-specific query packets.
|
214 |
|
|
extern int cyg_hal_stub_process_query (char *p, char *b, int n);
|
215 |
|
|
#define CYG_HAL_STUB_PROCESS_QUERY(__pkt__, __buf__, __bufsz__) \
|
216 |
|
|
cyg_hal_stub_process_query ((__pkt__), (__buf__), (__bufsz__))
|
217 |
|
|
|
218 |
|
|
// These masks are used to protect the user from writing to reserved bits
|
219 |
|
|
// of the control registers.
|
220 |
|
|
#define REG_CR4_MASK 0x000007FF
|
221 |
|
|
#define REG_CR3_MASK 0xFFFFF018
|
222 |
|
|
#define REG_CR2_MASK 0xFFFFFFFF
|
223 |
|
|
#define REG_CR0_MASK 0xE005003F
|
224 |
|
|
#endif
|
225 |
|
|
|
226 |
|
|
/* Find out what our last trap was. */
|
227 |
|
|
extern int __get_trap_number(void) ;
|
228 |
|
|
|
229 |
|
|
/* Given a trap number, compute the signal code for it. */
|
230 |
|
|
extern int __computeSignal(unsigned int trap_number) ;
|
231 |
|
|
|
232 |
|
|
/* Enable single stepping after the next user resume instruction. */
|
233 |
|
|
extern void __single_step(void) ;
|
234 |
|
|
extern void __clear_single_step(void) ;
|
235 |
|
|
|
236 |
|
|
extern void __install_breakpoints(void) ;
|
237 |
|
|
extern void __clear_breakpoints(void) ;
|
238 |
|
|
|
239 |
|
|
|
240 |
|
|
//---------------------------------------------------------------------------
|
241 |
|
|
#endif /* CYGONCE_HAL_I386_STUB_H */
|
242 |
|
|
// End of i386_stub.h
|