GNU Binutils with patches for OS216
修订版 | 24a2872af0e6d962b1b1a8207183e64ce7a1344d (tree) |
---|---|
时间 | 2002-08-30 03:22:44 |
作者 | Andrew Cagney <cagney@redh...> |
Commiter | Andrew Cagney |
2002-08-28 Andrew Cagney <cagney@redhat.com>
* osabi.c (gdbarch_init_osabi): Allow a NULL abfd.
(gdb_osabi_names): Add "RedBoot".
* osabi.h (gdb_osabi): Add GDB_OSABI_REDBOOT.
* i386-tdep.c (i386_gdbarch_init): Force RedBoot OSABI.
* i386-tdep.h (i386_pseudo_register_read): Declare.
(i386_pseudo_register_write): Declare.
(i386_register_virtual_type): Declare.
(i386_register_reggroup_p): Declare.
* i386-tdep.c (i386_pseudo_register_read): Make global.
(i386_pseudo_register_write): Make global.
(i386_register_reggroup_p): Make global.
(i386_register_virtual_type): Make global.
* config/i386/embed.mt (TDEPFILES): Add i386-rb-tdep.c.
(TM_FILE): Set to tm-embed.h.
* config/i386/tm-embed.h: New file.
* i386-rb-tdep.c: New file. Based on code by Fernando Nasser.
* remote.c (remote_fetch_registers): Call fetch_register_using_p.
(fetch_register_using_p): New function.
(init_remote_state): If defined, use GPACKET_UPPER_BOUND_HACK to
identify a register that isn't in the G packet.
@@ -1,3 +1,29 @@ | ||
1 | +2002-08-28 Andrew Cagney <cagney@redhat.com> | |
2 | + | |
3 | + * osabi.c (gdbarch_init_osabi): Allow a NULL abfd. | |
4 | + (gdb_osabi_names): Add "RedBoot". | |
5 | + * osabi.h (gdb_osabi): Add GDB_OSABI_REDBOOT. | |
6 | + * i386-tdep.c (i386_gdbarch_init): Force RedBoot OSABI. | |
7 | + | |
8 | + * i386-tdep.h (i386_pseudo_register_read): Declare. | |
9 | + (i386_pseudo_register_write): Declare. | |
10 | + (i386_register_virtual_type): Declare. | |
11 | + (i386_register_reggroup_p): Declare. | |
12 | + * i386-tdep.c (i386_pseudo_register_read): Make global. | |
13 | + (i386_pseudo_register_write): Make global. | |
14 | + (i386_register_reggroup_p): Make global. | |
15 | + (i386_register_virtual_type): Make global. | |
16 | + | |
17 | + * config/i386/embed.mt (TDEPFILES): Add i386-rb-tdep.c. | |
18 | + (TM_FILE): Set to tm-embed.h. | |
19 | + * config/i386/tm-embed.h: New file. | |
20 | + * i386-rb-tdep.c: New file. Based on code by Fernando Nasser. | |
21 | + | |
22 | + * remote.c (remote_fetch_registers): Call fetch_register_using_p. | |
23 | + (fetch_register_using_p): New function. | |
24 | + (init_remote_state): If defined, use GPACKET_UPPER_BOUND_HACK to | |
25 | + identify a register that isn't in the G packet. | |
26 | + | |
1 | 27 | 2002-08-28 Andrew Cagney <ac131313@redhat.com> |
2 | 28 | |
3 | 29 | * infcmd.c (registers_info): Pass start, instead of addr_exp, to |
@@ -1,3 +1,3 @@ | ||
1 | 1 | # Target: Embedded Intel 386 |
2 | -TDEPFILES= i386-tdep.o i387-tdep.o | |
3 | -TM_FILE= tm-i386.h | |
2 | +TDEPFILES= i386-tdep.o i387-tdep.o i386-rb-tdep.o | |
3 | +TM_FILE= tm-embed.h |
@@ -0,0 +1,862 @@ | ||
1 | +/* Intel 386 target-dependent stuff for the codetap target. | |
2 | + | |
3 | + Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, | |
4 | + 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. | |
5 | + | |
6 | + This file is part of GDB. | |
7 | + | |
8 | + This program is free software; you can redistribute it and/or modify | |
9 | + it under the terms of the GNU General Public License as published by | |
10 | + the Free Software Foundation; either version 2 of the License, or | |
11 | + (at your option) any later version. | |
12 | + | |
13 | + This program is distributed in the hope that it will be useful, | |
14 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | + GNU General Public License for more details. | |
17 | + | |
18 | + You should have received a copy of the GNU General Public License | |
19 | + along with this program; if not, write to the Free Software | |
20 | + Foundation, Inc., 59 Temple Place - Suite 330, | |
21 | + Boston, MA 02111-1307, USA. */ | |
22 | + | |
23 | +#include "defs.h" | |
24 | +#include "gdb_string.h" | |
25 | +#include "frame.h" | |
26 | +#include "inferior.h" | |
27 | +#include "gdbcore.h" | |
28 | +#include "objfiles.h" | |
29 | +#include "target.h" | |
30 | +#include "floatformat.h" | |
31 | +#include "symfile.h" | |
32 | +#include "symtab.h" | |
33 | +#include "gdbcmd.h" | |
34 | +#include "command.h" | |
35 | +#include "arch-utils.h" | |
36 | +#include "regcache.h" | |
37 | +#include "doublest.h" | |
38 | +#include "value.h" | |
39 | +#include "gdb_assert.h" | |
40 | +#include "reggroups.h" | |
41 | + | |
42 | +#include "i386-tdep.h" | |
43 | +#include "i387-tdep.h" | |
44 | + | |
45 | +#include <ctype.h> | |
46 | + | |
47 | +/* System registers. */ | |
48 | + | |
49 | +static struct type *builtin_type_i386_gdtr (void); | |
50 | +static struct type *builtin_type_i386_ldtr (void); | |
51 | +static struct type *builtin_type_i386_cr0 (void); | |
52 | +static struct type *builtin_type_i386_cr2 (void); | |
53 | +static struct type *builtin_type_i386_cr3 (void); | |
54 | +static struct type *builtin_type_i386_cr4 (void); | |
55 | +static struct type *builtin_type_i386_msr (void); | |
56 | + | |
57 | +struct i386_sys_reg | |
58 | +{ | |
59 | + const char *name; | |
60 | + struct type *(*type) (void); | |
61 | +}; | |
62 | + | |
63 | +struct i386_sys_reg i386_sys_regs[] = { | |
64 | + { "cr0", builtin_type_i386_cr0 }, | |
65 | + { "cr2", builtin_type_i386_cr2 }, | |
66 | + { "cr3", builtin_type_i386_cr3 }, | |
67 | + { "cr4", builtin_type_i386_cr4 }, | |
68 | + { "gdtr", builtin_type_i386_gdtr }, | |
69 | + { "idtr", builtin_type_i386_gdtr }, | |
70 | + { "ldtr", builtin_type_i386_ldtr }, | |
71 | + { "tr", builtin_type_i386_ldtr }, | |
72 | + { "", builtin_type_i386_msr } | |
73 | +}; | |
74 | +static const int num_sys_regs = (sizeof i386_sys_regs | |
75 | + / sizeof i386_sys_regs[0]); | |
76 | + | |
77 | +static int | |
78 | +regnum_to_sysnum (int regnum) | |
79 | +{ | |
80 | + return regnum - I386_SSE_NUM_REGS; | |
81 | +} | |
82 | + | |
83 | +static int | |
84 | +sys_regnum_p (int regnum) | |
85 | +{ | |
86 | + int sysnum = regnum_to_sysnum (regnum); | |
87 | + return (sysnum >= 0 && sysnum < num_sys_regs); | |
88 | +} | |
89 | + | |
90 | +static int | |
91 | +msr_regnum () | |
92 | +{ | |
93 | + /* The last SYSREG is special, it is used to access Red Boot's MSR | |
94 | + registers. Find the regnum of the first SYSREG by reversing the | |
95 | + effects of regnum_to_sysregnum. */ | |
96 | + return (-regnum_to_sysnum (0)) + num_sys_regs - 1; | |
97 | +} | |
98 | + | |
99 | +/* Red Boot's MSR registers. They are accessed using a single real | |
100 | + MSR register. */ | |
101 | + | |
102 | +struct i386_msr_reg | |
103 | +{ | |
104 | + const char *name; | |
105 | + long address; /* MSRs have a cardinal pnum. */ | |
106 | +}; | |
107 | + | |
108 | +struct i386_msr_reg i386_msr_regs[] = { | |
109 | + { "P5_MC_ADDR", 0 }, /* Machine-Check Error Address */ | |
110 | + { "P5_MC_TYPE", 1 }, /* Machine-Check Error Type */ | |
111 | + { "TSC", 16 }, /* Time Stamp Counter */ | |
112 | + { "BBL_CR_OVRD", 23 }, /* Platform type for microcode updates */ | |
113 | + { "APICBASE", 27 }, /* APIC Base Address */ | |
114 | + { "EBL_CR_POWERON", 42 }, /* Power On Configuration Register */ | |
115 | + { "TEST_CTL", 51 }, /* Test Control Register */ | |
116 | + { "BIOS_UPDT_TRIG", 121 }, /* BIOS Update Trigger Register */ | |
117 | + { "BBL_CR_D0", 136 }, /* L2 Chunk 0 data register D[63:0] */ | |
118 | + { "BBL_CR_D1", 137 }, /* L2 Chunk 1 data register D[63:0] */ | |
119 | + { "BBL_CR_D2", 138 }, /* L2 Chunk 2 data register D[63:0] */ | |
120 | + { "BBL_CR_D3", 139 }, /* L2 Chunk 3 data register D[63:0] */ | |
121 | + { "BIOS_SIGN", 139 }, /* BIOS Update Signature Register */ | |
122 | + { "PERFCT0", 193 }, /* Performance Counter 0 */ | |
123 | + { "PERFCT1", 194 }, /* Performance Counter 1 */ | |
124 | + { "MTRRcap", 254 }, /* MTR Information */ | |
125 | + { "BBL_CR_ADDR", 278 }, /* L2 Address Register */ | |
126 | + { "BBL_CR_DECC", 280 }, /* L2 Data ECC Register */ | |
127 | + { "BBL_CR_CTL", 281 }, /* L2 Control Register */ | |
128 | + { "BBL_CR_TRIG", 282 }, /* L2 Trigger Register */ | |
129 | + { "BBL_CR_BUSY", 283 }, /* L2 Busy Register */ | |
130 | + { "BBL_CR_CTL3", 286 }, /* L2 Control Register 3 */ | |
131 | + { "MCG_CAP", 377 }, /* Machine-Check Architecture Implementation */ | |
132 | + { "MCG_STATUS", 378 }, /* Machine-Check Status */ | |
133 | + { "MCG_CTL", 379 }, /* Machine-Check Control */ | |
134 | + { "EVNTSEL0", 390 }, /* Event Select 0 */ | |
135 | + { "EVNTSEL1", 391 }, /* Event Select 1 */ | |
136 | + { "DEBUGCTLMSR", 473 }, /* Debug Control */ | |
137 | + { "LASTBRANCHFROMIP", 475 }, /* LastBranchFromIP */ | |
138 | + { "LASTBRANCTOIP", 476 }, /* LastBranchToIP */ | |
139 | + { "LASTINTFROMIP", 477 }, /* LastExceptionFromIP */ | |
140 | + { "LASTINTTOIP", 478 }, /* LastExceptionToIP */ | |
141 | + { "ROB_CR_BKUPTMPDR6", 480 }, /* */ | |
142 | + { "MTRRphysBase0", 512 }, /* Variable Range MTRR Base Address and Type */ | |
143 | + { "MTRRphysMask0", 513 }, /* Variable Range MTRR Address Range Mask */ | |
144 | + { "MTRRphysBase1", 514 }, /* Variable Range MTRR Base Address and Type */ | |
145 | + { "MTRRphysMask1", 515 }, /* Variable Range MTRR Address Range Mask */ | |
146 | + { "MTRRphysBase2", 516 }, /* Variable Range MTRR Base Address and Type */ | |
147 | + { "MTRRphysMask2", 517 }, /* Variable Range MTRR Address Range Mask */ | |
148 | + { "MTRRphysBase3", 518 }, /* Variable Range MTRR Base Address and Type */ | |
149 | + { "MTRRphysMask3", 519 }, /* Variable Range MTRR Address Range Mask */ | |
150 | + { "MTRRphysBase4", 520 }, /* Variable Range MTRR Base Address and Type */ | |
151 | + { "MTRRphysMask4", 521 }, /* Variable Range MTRR Address Range Mask */ | |
152 | + { "MTRRphysBase5", 522 }, /* Variable Range MTRR Base Address and Type */ | |
153 | + { "MTRRphysMask5", 523 }, /* Variable Range MTRR Address Range Mask */ | |
154 | + { "MTRRphysBase6", 524 }, /* Variable Range MTRR Base Address and Type */ | |
155 | + { "MTRRphysMask6", 525 }, /* Variable Range MTRR Address Range Mask */ | |
156 | + { "MTRRphysBase7", 526 }, /* Variable Range MTRR Base Address and Type */ | |
157 | + { "MTRRphysMask7", 527 }, /* Variable Range MTRR Address Range Mask */ | |
158 | + { "MTRRfix64K_0000", 592 }, /* Fixed Range MTRR */ | |
159 | + { "MTRRfix16K_8000", 600 }, /* Fixed Range MTRR */ | |
160 | + { "MTRRfix16K_a000", 601 }, /* Fixed Range MTRR */ | |
161 | + { "MTRRfix4K_c000", 616 }, /* Fixed Range MTRR */ | |
162 | + { "MTRRfix4K_c800", 617 }, /* Fixed Range MTRR */ | |
163 | + { "MTRRfix4K_d000", 618 }, /* Fixed Range MTRR */ | |
164 | + { "MTRRfix4K_d800", 619 }, /* Fixed Range MTRR */ | |
165 | + { "MTRRfix4K_e000", 620 }, /* Fixed Range MTRR */ | |
166 | + { "MTRRfix4K_e800", 621 }, /* Fixed Range MTRR */ | |
167 | + { "MTRRfix4K_f000", 622 }, /* Fixed Range MTRR */ | |
168 | + { "MTRRfix4K_f800", 623 }, /* Fixed Range MTRR */ | |
169 | + { "MTRRdefType", 767 }, /* Default Properties of non-MTRR memory */ | |
170 | + { "MC0_CTL", 1024 }, /* Bank 0 Machine-Check Error Reporting Control */ | |
171 | + { "MC0_STATUS", 1025 }, /* Bank 0 Machine-Check Error Reporting Status */ | |
172 | + { "MC0_ADDR", 1026 }, /* Bank 0 Machine-Check Error Reporting Mask */ | |
173 | + { "MC1_CTL", 1028 }, /* Bank 1 Machine-Check Error Reporting Control */ | |
174 | + { "MC1_STATUS", 1029 }, /* Bank 1 Machine-Check Error Reporting Status */ | |
175 | + { "MC1_ADDR", 1030 }, /* Bank 1 Machine-Check Error Reporting Mask */ | |
176 | + { "MC2_CTL", 1032 }, /* Bank 2 Machine-Check Error Reporting Control */ | |
177 | + { "MC2_STATUS", 1033 }, /* Bank 2 Machine-Check Error Reporting Status */ | |
178 | + { "MC2_ADDR", 1034 }, /* Bank 2 Machine-Check Error Reporting Mask */ | |
179 | + { "MC4_CTL", 1036 }, /* Bank 4 Machine-Check Error Reporting Control */ | |
180 | + { "MC4_STATUS", 1037 }, /* Bank 4 Machine-Check Error Reporting Status */ | |
181 | + { "MC4_ADDR", 1038 }, /* Bank 4 Machine-Check Error Reporting Mask */ | |
182 | + { "MC3_CTL", 1040 }, /* Bank 3 Machine-Check Error Reporting Control */ | |
183 | + { "MC3_STATUS", 1041 }, /* Bank 3 Machine-Check Error Reporting Status */ | |
184 | + { "MC3_ADDR", 1042 } /* Bank 3 Machine-Check Error Reporting Mask */ | |
185 | +}; | |
186 | +static const long num_msr_regs = (sizeof i386_msr_regs | |
187 | + / sizeof i386_msr_regs[0]); | |
188 | +/* FIXME: cagney/2002-08-28: Just ``know'' that there are 8 MSR regs. */ | |
189 | +#define NUM_I386_MMX_REGS 8 /*MAGIC*/ | |
190 | + | |
191 | +static int | |
192 | +regnum_to_msrnum (int regnum) | |
193 | +{ | |
194 | + return regnum - (NUM_REGS + NUM_I386_MMX_REGS); | |
195 | +} | |
196 | + | |
197 | +static int | |
198 | +msr_regnum_p (int regnum) | |
199 | +{ | |
200 | + int msrnum = regnum_to_msrnum (regnum); | |
201 | + return (msrnum >= 0 && msrnum < num_msr_regs); | |
202 | +} | |
203 | + | |
204 | +/* Query the target for selected MSR, if available. This also tells | |
205 | + the target which MSR we are interested in. */ | |
206 | + | |
207 | +static int | |
208 | +i386_query_msr_regnum (int regnum) | |
209 | +{ | |
210 | + int size = 0; | |
211 | + char *buf; | |
212 | + char *rets; | |
213 | + char *qstr; | |
214 | + struct cleanup *saved_cleanups = make_cleanup (null_cleanup, NULL); | |
215 | + | |
216 | + gdb_assert (msr_regnum_p (regnum)); | |
217 | + | |
218 | + /* Get the current buffer size. */ | |
219 | + if (current_target.to_query == NULL) | |
220 | + return -1; | |
221 | + size = 0; | |
222 | + target_query ('M', "SR", NULL, &size); | |
223 | + | |
224 | + buf = xmalloc (size); | |
225 | + make_cleanup (xfree, buf); | |
226 | + | |
227 | + /* Now query the MSR info. */ | |
228 | + xasprintf (&qstr, "SR,%lx,%s", | |
229 | + i386_msr_regs[regnum_to_msrnum (regnum)].address, | |
230 | + i386_msr_regs[regnum_to_msrnum (regnum)].name); | |
231 | + make_cleanup (xfree, qstr); | |
232 | + | |
233 | + if (target_query ('M', qstr, buf, &size) < 0) | |
234 | + return -1; | |
235 | + | |
236 | + if ((strlen (buf) == 0) | |
237 | + || (strcmp (buf, "INVALID") == 0)) | |
238 | + { | |
239 | + do_cleanups (saved_cleanups); | |
240 | + return -1; | |
241 | + } | |
242 | + | |
243 | + do_cleanups (saved_cleanups); | |
244 | + return 0; | |
245 | +} | |
246 | + | |
247 | +/* Return the name of register REG. */ | |
248 | + | |
249 | +const char * | |
250 | +i386_rb_register_name (int regnum) | |
251 | +{ | |
252 | + if (sys_regnum_p (regnum)) | |
253 | + return i386_sys_regs[regnum_to_sysnum (regnum)].name; | |
254 | + if (msr_regnum_p (regnum)) | |
255 | + return i386_msr_regs[regnum_to_msrnum (regnum)].name; | |
256 | + return i386_register_name (regnum); | |
257 | +} | |
258 | + | |
259 | +static struct type * | |
260 | +builtin_type_i386_gdtr (void) | |
261 | +{ | |
262 | + /* Construct a type for the GDTR and IDTR MM registers. The type | |
263 | + we're building is this: */ | |
264 | +#if 0 | |
265 | + struct builtin_type_i386_gdtr | |
266 | + { | |
267 | + uint32_t base; | |
268 | + uint16_t lim; | |
269 | + }; | |
270 | +#endif | |
271 | + | |
272 | + static struct type *t; | |
273 | + struct field *f; | |
274 | + | |
275 | + if (t != NULL) | |
276 | + return t; | |
277 | + | |
278 | + f = (struct field *) xmalloc (sizeof (*f) * 2); | |
279 | + memset (f, 0, sizeof (*f) * 2); | |
280 | + | |
281 | + FIELD_TYPE (f[0])= builtin_type_uint32; | |
282 | + FIELD_NAME (f[0])= "base"; | |
283 | + FIELD_BITPOS (f[0]) = 0; | |
284 | + | |
285 | + FIELD_TYPE (f[1])= builtin_type_uint16; | |
286 | + FIELD_NAME (f[1])= "lim"; | |
287 | + FIELD_BITPOS (f[1]) = 32; | |
288 | + | |
289 | + /* Build a struct type with those fields. */ | |
290 | + t = init_type (TYPE_CODE_STRUCT, 6, 0, 0, 0); | |
291 | + TYPE_NFIELDS (t) = 2; | |
292 | + TYPE_FIELDS (t) = f; | |
293 | + TYPE_TAG_NAME (t) = "builtin_type_i386_gdtr"; | |
294 | + | |
295 | + return t; | |
296 | +} | |
297 | + | |
298 | +static struct type * | |
299 | +builtin_type_i386_ldtr (void) | |
300 | +{ | |
301 | + /* Construct a type for the LDTR and TR MM registers. The type | |
302 | + we're building is this: */ | |
303 | +#if 0 | |
304 | + struct builtin_type_i386_ldtr | |
305 | + { | |
306 | + uint32_t base; | |
307 | + uint16_t lim; | |
308 | + struct | |
309 | + { | |
310 | + unsigned int index:13; | |
311 | + unsigned int TI:1; | |
312 | + unsigned int RPL:2; | |
313 | + } sel; | |
314 | + }; */ | |
315 | +#endif | |
316 | + | |
317 | + static struct type *t; /* The type we are creating. */ | |
318 | + struct type *ts; /* The type of selector part. */ | |
319 | + struct field *f; /* Fields of the main type struct. */ | |
320 | + struct field *fs; /* Fields of the selector part. */ | |
321 | + | |
322 | + if (t != NULL) | |
323 | + return t; | |
324 | + | |
325 | + /* First, make a type for the selector part. */ | |
326 | + fs = (struct field *) xmalloc (sizeof (*fs) * 3); | |
327 | + memset (fs, 0, sizeof (*fs) * 3); | |
328 | + | |
329 | + /* Note that we reverse the order so we see the bit fields from | |
330 | + left to right, as in a manual figure. */ | |
331 | + | |
332 | + FIELD_TYPE (fs[0]) = builtin_type_unsigned_int; | |
333 | + FIELD_NAME (fs[0]) = "index"; | |
334 | + FIELD_BITPOS (fs[0]) = 3; | |
335 | + FIELD_BITSIZE (fs[0]) = 13; | |
336 | + | |
337 | + FIELD_TYPE (fs[1]) = builtin_type_unsigned_int; | |
338 | + FIELD_NAME (fs[1]) = "TI"; | |
339 | + FIELD_BITPOS (fs[1]) = 2; | |
340 | + FIELD_BITSIZE (fs[1]) = 1; | |
341 | + | |
342 | + FIELD_TYPE (fs[2]) = builtin_type_unsigned_int; | |
343 | + FIELD_NAME (fs[2]) = "RPL"; | |
344 | + FIELD_BITPOS (fs[2]) = 0; | |
345 | + FIELD_BITSIZE (fs[2]) = 2; | |
346 | + | |
347 | + /* Build a struct type with those fields. */ | |
348 | + ts = init_type (TYPE_CODE_STRUCT, 2, 0, 0, 0); | |
349 | + TYPE_NFIELDS (ts) = 3; | |
350 | + TYPE_FIELDS (ts) = fs; | |
351 | + TYPE_TAG_NAME (ts) = "builtin_type_i386_ldtr_selector"; | |
352 | + | |
353 | + /* Now build the main type. */ | |
354 | + f = (struct field *) xmalloc (sizeof (*f) * 3); | |
355 | + memset (f, 0, sizeof (*f) * 3); | |
356 | + | |
357 | + FIELD_TYPE (f[0])= builtin_type_uint32; | |
358 | + FIELD_NAME (f[0])= "base"; | |
359 | + FIELD_BITPOS (f[0]) = 0; | |
360 | + | |
361 | + FIELD_TYPE (f[1]) = builtin_type_uint16; | |
362 | + FIELD_NAME (f[1]) = "lim"; | |
363 | + FIELD_BITPOS (f[1]) = 32; | |
364 | + | |
365 | + FIELD_TYPE (f[2])= ts; | |
366 | + FIELD_NAME (f[2])= "sel"; | |
367 | + FIELD_BITPOS (f[2]) = 48; | |
368 | + | |
369 | + /* Build a struct type with those fields. */ | |
370 | + t = init_type (TYPE_CODE_STRUCT, 8, 0, 0, 0); | |
371 | + TYPE_NFIELDS (t) = 3; | |
372 | + TYPE_FIELDS (t) = f; | |
373 | + TYPE_TAG_NAME (t) = "builtin_type_i386_ldtr"; | |
374 | + | |
375 | + return t; | |
376 | +} | |
377 | + | |
378 | +static struct type * | |
379 | +builtin_type_i386_cr0 (void) | |
380 | +{ | |
381 | + /* Construct a type for the CR0 register. The type we're building | |
382 | + is this: */ | |
383 | +#if 0 | |
384 | + union builtin_type_i386_cr0 | |
385 | + { | |
386 | + void * cr0; | |
387 | + struct __builtin_i386_cr0_bits | |
388 | + { | |
389 | + unsigned PG:1; | |
390 | + unsigned CD:1; | |
391 | + unsigned NW:1; | |
392 | + /* We skip 10 reserved bits here. */ | |
393 | + unsigned AM:1; | |
394 | + /* We skip 1 reserved bit here. */ | |
395 | + unsigned WP:1; | |
396 | + /* We skip 10 reserved bits here. */ | |
397 | + unsigned NE:1; | |
398 | + unsigned ET:1; | |
399 | + unsigned TS:1; | |
400 | + unsigned EM:1; | |
401 | + unsigned MP:1; | |
402 | + unsigned PE:1; | |
403 | + } bits; | |
404 | + }; | |
405 | +#endif | |
406 | + /* Note that we cannot create a structure like that in C because we | |
407 | + could not skip the reserved bits and the order would be the | |
408 | + reverse of what we want (we want to see bit names from left to | |
409 | + right, as in a manual figure). */ | |
410 | + | |
411 | + static struct type *t; /* The type we are creating. */ | |
412 | + struct type *tp; /* The type of the pointer part. */ | |
413 | + struct type *tb; /* The type of the bitfields part. */ | |
414 | + struct field *fu; /* Fields of the union. */ | |
415 | + struct field *fs; /* Fields of the struct. */ | |
416 | + | |
417 | + if (t != NULL) | |
418 | + return t; | |
419 | + | |
420 | + /* Create fields for each group of bits. */ | |
421 | + fs = (struct field *) xmalloc (sizeof (*fs) * 11); | |
422 | + memset (fs, 0, sizeof (*fs) * 11); | |
423 | + | |
424 | + /* Note that we reverse the order of the fields so they are printed | |
425 | + as we would see then in a manual figure, left to right. */ | |
426 | + | |
427 | + FIELD_TYPE (fs[10]) = builtin_type_unsigned_int; | |
428 | + FIELD_NAME (fs[10]) = "PE"; | |
429 | + FIELD_BITPOS (fs[10]) = 0; | |
430 | + FIELD_BITSIZE (fs[10]) = 1; | |
431 | + | |
432 | + FIELD_TYPE (fs[9]) = builtin_type_unsigned_int; | |
433 | + FIELD_NAME (fs[9]) = "MP"; | |
434 | + FIELD_BITPOS (fs[9]) = 1; | |
435 | + FIELD_BITSIZE (fs[9]) = 1; | |
436 | + | |
437 | + FIELD_TYPE (fs[8]) = builtin_type_unsigned_int; | |
438 | + FIELD_NAME (fs[8]) = "EM"; | |
439 | + FIELD_BITPOS (fs[8]) = 2; | |
440 | + FIELD_BITSIZE (fs[8]) = 1; | |
441 | + | |
442 | + FIELD_TYPE (fs[7]) = builtin_type_unsigned_int; | |
443 | + FIELD_NAME (fs[7]) = "TS"; | |
444 | + FIELD_BITPOS (fs[7]) = 3; | |
445 | + FIELD_BITSIZE (fs[7]) = 1; | |
446 | + | |
447 | + FIELD_TYPE (fs[6]) = builtin_type_unsigned_int; | |
448 | + FIELD_NAME (fs[6]) = "ET"; | |
449 | + FIELD_BITPOS (fs[6]) = 4; | |
450 | + FIELD_BITSIZE (fs[6]) = 1; | |
451 | + | |
452 | + FIELD_TYPE (fs[5]) = builtin_type_unsigned_int; | |
453 | + FIELD_NAME (fs[5]) = "NE"; | |
454 | + FIELD_BITPOS (fs[5]) = 5; | |
455 | + FIELD_BITSIZE (fs[5]) = 1; | |
456 | + | |
457 | + FIELD_TYPE (fs[4]) = builtin_type_unsigned_int; | |
458 | + FIELD_NAME (fs[4]) = "WP"; | |
459 | + FIELD_BITPOS (fs[4]) = 16; | |
460 | + FIELD_BITSIZE (fs[4]) = 1; | |
461 | + | |
462 | + FIELD_TYPE (fs[3]) = builtin_type_unsigned_int; | |
463 | + FIELD_NAME (fs[3]) = "AM"; | |
464 | + FIELD_BITPOS (fs[3]) = 18; | |
465 | + FIELD_BITSIZE (fs[3]) = 1; | |
466 | + | |
467 | + FIELD_TYPE (fs[2]) = builtin_type_unsigned_int; | |
468 | + FIELD_NAME (fs[2]) = "NW"; | |
469 | + FIELD_BITPOS (fs[2]) = 29; | |
470 | + FIELD_BITSIZE (fs[2]) = 1; | |
471 | + | |
472 | + FIELD_TYPE (fs[1]) = builtin_type_unsigned_int; | |
473 | + FIELD_NAME (fs[1]) = "CD"; | |
474 | + FIELD_BITPOS (fs[1]) = 30; | |
475 | + FIELD_BITSIZE (fs[1]) = 1; | |
476 | + | |
477 | + FIELD_TYPE (fs[0]) = builtin_type_unsigned_int; | |
478 | + FIELD_NAME (fs[0]) = "PG"; | |
479 | + FIELD_BITPOS (fs[0]) = 31; | |
480 | + FIELD_BITSIZE (fs[0]) = 1; | |
481 | + | |
482 | + /* Build a struct type with these bitfields. */ | |
483 | + tb = init_type (TYPE_CODE_STRUCT, 4, 0, 0, 0); | |
484 | + TYPE_NFIELDS (tb) = 11; | |
485 | + TYPE_FIELDS (tb) = fs; | |
486 | + TYPE_TAG_NAME (tb) = "builtin_type_i386_cr0_bits"; | |
487 | + | |
488 | + /* Create the pointer part. */ | |
489 | + tp = make_pointer_type (builtin_type_void, NULL); | |
490 | + | |
491 | + /* Now make our type as the union of the pointer and the bitfield parts. */ | |
492 | + fu = (struct field *) xmalloc (sizeof (*fu) * 2); | |
493 | + memset (fu, 0, sizeof (*fu) * 2); | |
494 | + | |
495 | + FIELD_TYPE (fu[0]) = tp; | |
496 | + FIELD_NAME (fu[0]) = "cr0"; | |
497 | + | |
498 | + FIELD_TYPE (fu[1]) = tb; | |
499 | + FIELD_NAME (fu[1]) = "bits"; | |
500 | + | |
501 | + /* Build a union type with those fields. */ | |
502 | + t = init_type (TYPE_CODE_UNION, 4, 0, 0, 0); | |
503 | + TYPE_NFIELDS (t) = 2; | |
504 | + TYPE_FIELDS (t) = fu; | |
505 | + TYPE_TAG_NAME (t) = "builtin_type_i386_cr0"; | |
506 | + | |
507 | + return t; | |
508 | +} | |
509 | + | |
510 | +static struct type * | |
511 | +builtin_type_i386_cr2 (void) | |
512 | +{ | |
513 | + return builtin_type_uint32; | |
514 | +} | |
515 | + | |
516 | +static struct type * | |
517 | +builtin_type_i386_cr3 (void) | |
518 | +{ | |
519 | + /* Construct a type for the PDBR (CR3). The type we're building is | |
520 | + this: */ | |
521 | +#if 0 | |
522 | + union builtin_type_i386_cr3 | |
523 | + { | |
524 | + void * cr3; | |
525 | + struct builtin_type_i386_pdbr | |
526 | + { | |
527 | + unsigned int PDbase:20; | |
528 | + /* We skip 7 reserved bits here. */ | |
529 | + unsigned int PCD:1; | |
530 | + unsigned int PWT:1; | |
531 | + /* We ignore 3 reserved bits here. */ | |
532 | + }; | |
533 | + }; | |
534 | +#endif | |
535 | + | |
536 | + struct type *t; /* The type we are creating. */ | |
537 | + struct type *tp; /* The type of the pointer part. */ | |
538 | + struct type *tb; /* The type of the bitfields part. */ | |
539 | + struct field *fu; /* Fields of the union. */ | |
540 | + struct field *fs; /* Fields of the struct. */ | |
541 | + | |
542 | + fs = (struct field *) xmalloc (sizeof (*fs) * 3); | |
543 | + memset (fs, 0, sizeof (*fs) * 3); | |
544 | + | |
545 | + FIELD_TYPE (fs[0])= builtin_type_unsigned_int; | |
546 | + FIELD_NAME (fs[0])= "PDbase"; | |
547 | + FIELD_BITPOS (fs[0]) = 12; | |
548 | + FIELD_BITSIZE (fs[0]) = 20; | |
549 | + | |
550 | + FIELD_TYPE (fs[1])= builtin_type_unsigned_int; | |
551 | + FIELD_NAME (fs[1])= "PCD"; | |
552 | + FIELD_BITPOS (fs[1]) = 4; | |
553 | + FIELD_BITSIZE (fs[1]) = 1; | |
554 | + | |
555 | + FIELD_TYPE (fs[2])= builtin_type_unsigned_int; | |
556 | + FIELD_NAME (fs[2])= "PWT"; | |
557 | + FIELD_BITPOS (fs[2]) = 3; | |
558 | + FIELD_BITSIZE (fs[2]) = 1; | |
559 | + | |
560 | + /* Build a struct type with those fields. */ | |
561 | + tb = init_type (TYPE_CODE_STRUCT, 4, 0, 0, 0); | |
562 | + TYPE_NFIELDS (tb) = 3; | |
563 | + TYPE_FIELDS (tb) = fs; | |
564 | + TYPE_TAG_NAME (tb) = "builtin_type_i386_cr3_bits"; | |
565 | + | |
566 | + /* Create the pointer part. */ | |
567 | + tp = make_pointer_type (builtin_type_void, NULL); | |
568 | + | |
569 | + /* Now make our type as the union of the pointer and the bitfield parts. */ | |
570 | + fu = (struct field *) xmalloc (sizeof (*fu) * 2); | |
571 | + memset (fu, 0, sizeof (*fu) * 2); | |
572 | + | |
573 | + FIELD_TYPE (fu[0]) = tp; | |
574 | + FIELD_NAME (fu[0]) = "cr3"; | |
575 | + | |
576 | + FIELD_TYPE (fu[1]) = tb; | |
577 | + FIELD_NAME (fu[1]) = "bits"; | |
578 | + | |
579 | + /* Build a union type with those fields. */ | |
580 | + t = init_type (TYPE_CODE_UNION, 4, 0, 0, 0); | |
581 | + TYPE_NFIELDS (t) = 2; | |
582 | + TYPE_FIELDS (t) = fu; | |
583 | + TYPE_TAG_NAME (t) = "builtin_type_i386_cr3"; | |
584 | + | |
585 | + return t; | |
586 | +} | |
587 | + | |
588 | +static struct type * | |
589 | +builtin_type_i386_cr4 (void) | |
590 | +{ | |
591 | + /* Construct a type for the CR4 register. The type we're building | |
592 | + is this: */ | |
593 | +#if 0 | |
594 | + union builtin_type_i386_cr4 | |
595 | + { | |
596 | + void * cr0; | |
597 | + struct __builtin_i386_cr4_bits { | |
598 | + /* We skip the 21 reserved bits here. */ | |
599 | + unsigned OSXMMEXCPT:1; | |
600 | + unsigned OSFXSR:1; | |
601 | + unsigned PCE:1; | |
602 | + unsigned PGE:1; | |
603 | + unsigned MCE:1; | |
604 | + unsigned PAE:1; | |
605 | + unsigned PSE:1; | |
606 | + unsigned DE:1; | |
607 | + unsigned TSD:1; | |
608 | + unsigned PVI:1; | |
609 | + unsigned VME:1; | |
610 | + } bits; | |
611 | + }; | |
612 | +#endif | |
613 | + /* Note that we cannot create a structure like that in C because we | |
614 | + could not skip the reserved bits and the order would be the | |
615 | + reverse of what we want (we want to see bit names from left to | |
616 | + right, as in a manual figure). */ | |
617 | + | |
618 | + struct type *t; /* The type we are creating. */ | |
619 | + struct type *tp; /* The type of the pointer part. */ | |
620 | + struct type *tb; /* The type of the bitfields part. */ | |
621 | + struct field *fu; /* Fields of the union. */ | |
622 | + struct field *fs; /* Fields of the struct. */ | |
623 | + | |
624 | + /* Create fields for each group of bits. */ | |
625 | + fs = (struct field *) xmalloc (sizeof (*fs) * 11); | |
626 | + memset (fs, 0, sizeof (*fs) * 11); | |
627 | + | |
628 | + /* Note that we reverse the order of the fields so they are printed | |
629 | + as we would see then in a manual figure, left to right. */ | |
630 | + | |
631 | + FIELD_TYPE (fs[10]) = builtin_type_unsigned_int; | |
632 | + FIELD_NAME (fs[10]) = "VME"; | |
633 | + FIELD_BITPOS (fs[10]) = 0; | |
634 | + FIELD_BITSIZE (fs[10]) = 1; | |
635 | + | |
636 | + FIELD_TYPE (fs[9]) = builtin_type_unsigned_int; | |
637 | + FIELD_NAME (fs[9]) = "PVI"; | |
638 | + FIELD_BITPOS (fs[9]) = 1; | |
639 | + FIELD_BITSIZE (fs[9]) = 1; | |
640 | + | |
641 | + FIELD_TYPE (fs[8]) = builtin_type_unsigned_int; | |
642 | + FIELD_NAME (fs[8]) = "TSD"; | |
643 | + FIELD_BITPOS (fs[8]) = 2; | |
644 | + FIELD_BITSIZE (fs[8]) = 1; | |
645 | + | |
646 | + FIELD_TYPE (fs[7]) = builtin_type_unsigned_int; | |
647 | + FIELD_NAME (fs[7]) = "DE"; | |
648 | + FIELD_BITPOS (fs[7]) = 3; | |
649 | + FIELD_BITSIZE (fs[7]) = 1; | |
650 | + | |
651 | + FIELD_TYPE (fs[6]) = builtin_type_unsigned_int; | |
652 | + FIELD_NAME (fs[6]) = "PSE"; | |
653 | + FIELD_BITPOS (fs[6]) = 4; | |
654 | + FIELD_BITSIZE (fs[6]) = 1; | |
655 | + | |
656 | + FIELD_TYPE (fs[5]) = builtin_type_unsigned_int; | |
657 | + FIELD_NAME (fs[5]) = "PAE"; | |
658 | + FIELD_BITPOS (fs[5]) = 5; | |
659 | + FIELD_BITSIZE (fs[5]) = 1; | |
660 | + | |
661 | + FIELD_TYPE (fs[4]) = builtin_type_unsigned_int; | |
662 | + FIELD_NAME (fs[4]) = "MCE"; | |
663 | + FIELD_BITPOS (fs[4]) = 6; | |
664 | + FIELD_BITSIZE (fs[4]) = 1; | |
665 | + | |
666 | + FIELD_TYPE (fs[3]) = builtin_type_unsigned_int; | |
667 | + FIELD_NAME (fs[3]) = "PGE"; | |
668 | + FIELD_BITPOS (fs[3]) = 7; | |
669 | + FIELD_BITSIZE (fs[3]) = 1; | |
670 | + | |
671 | + FIELD_TYPE (fs[2]) = builtin_type_unsigned_int; | |
672 | + FIELD_NAME (fs[2]) = "PCE"; | |
673 | + FIELD_BITPOS (fs[2]) = 8; | |
674 | + FIELD_BITSIZE (fs[2]) = 1; | |
675 | + | |
676 | + FIELD_TYPE (fs[1]) = builtin_type_unsigned_int; | |
677 | + FIELD_NAME (fs[1]) = "OSFXSR"; | |
678 | + FIELD_BITPOS (fs[1]) = 9; | |
679 | + FIELD_BITSIZE (fs[1]) = 1; | |
680 | + | |
681 | + FIELD_TYPE (fs[0]) = builtin_type_unsigned_int; | |
682 | + FIELD_NAME (fs[0]) = "OSXMMEXCPT"; | |
683 | + FIELD_BITPOS (fs[0]) = 10; | |
684 | + FIELD_BITSIZE (fs[0]) = 1; | |
685 | + | |
686 | + /* Build a struct type with these bitfields. */ | |
687 | + tb = init_type (TYPE_CODE_STRUCT, 4, 0, 0, 0); | |
688 | + TYPE_NFIELDS (tb) = 11; | |
689 | + TYPE_FIELDS (tb) = fs; | |
690 | + TYPE_TAG_NAME (tb) = "builtin_type_i386_cr4_bits"; | |
691 | + | |
692 | + /* Create the pointer part. */ | |
693 | + tp = make_pointer_type (builtin_type_void, NULL); | |
694 | + | |
695 | + /* Now make our type as the union of the pointer and the bitfield parts. */ | |
696 | + fu = (struct field *) xmalloc (sizeof (*fu) * 2); | |
697 | + memset (fu, 0, sizeof (*fu) * 2); | |
698 | + | |
699 | + FIELD_TYPE (fu[0]) = tp; | |
700 | + FIELD_NAME (fu[0]) = "cr4"; | |
701 | + | |
702 | + FIELD_TYPE (fu[1]) = tb; | |
703 | + FIELD_NAME (fu[1]) = "bits"; | |
704 | + | |
705 | + /* Build a union type with those fields. */ | |
706 | + t = init_type (TYPE_CODE_UNION, 4, 0, 0, 0); | |
707 | + TYPE_NFIELDS (t) = 2; | |
708 | + TYPE_FIELDS (t) = fu; | |
709 | + TYPE_TAG_NAME (t) = "builtin_type_i386_cr4"; | |
710 | + | |
711 | + return t; | |
712 | +} | |
713 | + | |
714 | +static struct type * | |
715 | +builtin_type_i386_msr (void) | |
716 | +{ | |
717 | + return builtin_type_uint64; | |
718 | +} | |
719 | + | |
720 | +/* Return the GDB type object for the "standard" data type of data in | |
721 | + register REGNUM. Perhaps %esi and %edi should go here, but | |
722 | + potentially they could be used for things other than address. */ | |
723 | + | |
724 | +struct type * | |
725 | +i386_rb_register_virtual_type (int regnum) | |
726 | +{ | |
727 | + if (sys_regnum_p (regnum)) | |
728 | + return i386_sys_regs[regnum_to_sysnum (regnum)].type (); | |
729 | + if (msr_regnum_p (regnum)) | |
730 | + return builtin_type_i386_msr (); | |
731 | + return i386_register_virtual_type (regnum); | |
732 | +} | |
733 | + | |
734 | +static struct reggroup *msr_reggroup; | |
735 | + | |
736 | +static int | |
737 | +i386_rb_register_regroup_p (struct gdbarch *gdbarch, int regnum, | |
738 | + struct reggroup *group) | |
739 | +{ | |
740 | + if (group == system_reggroup) | |
741 | + return sys_regnum_p (regnum); | |
742 | + if (group == msr_reggroup) | |
743 | + return msr_regnum_p (regnum); | |
744 | + if (sys_regnum_p (regnum) || msr_regnum_p (regnum)) | |
745 | + return 0; | |
746 | + return i386_register_reggroup_p (gdbarch, regnum, group); | |
747 | +} | |
748 | + | |
749 | +int | |
750 | +i386_rb_gpacket_upper_bound_hack (void) | |
751 | +{ | |
752 | + return I386_SSE_NUM_REGS; | |
753 | +} | |
754 | + | |
755 | +int | |
756 | +i386_rb_next_abi_register (struct gdbarch *gdbarch, int regnum) | |
757 | +{ | |
758 | + if (regnum < 0) | |
759 | + return 0; | |
760 | + regnum++; | |
761 | + if (regnum >= I386_SSE_NUM_REGS) | |
762 | + return -1; | |
763 | + return regnum; | |
764 | +} | |
765 | + | |
766 | +/* Map registers onto their real counterparts. Note these functions | |
767 | + need sibling changes in the code that does the same thing for | |
768 | + registers on a frame. */ | |
769 | + | |
770 | +static void | |
771 | +i386_msr_register_read (struct gdbarch *gdbarch, struct regcache *regcache, | |
772 | + int regnum, void *buf) | |
773 | +{ | |
774 | + /* ULGH. */ | |
775 | + gdb_assert (msr_regnum_p (regnum)); | |
776 | + if (i386_query_msr_regnum (regnum) == 0) | |
777 | + { | |
778 | + /* Invalidate the MSR in the register cache forcing a re-read. */ | |
779 | + register_valid[msr_regnum ()] = 0; | |
780 | + regcache_raw_read (regcache, msr_regnum (), buf); | |
781 | + } | |
782 | +} | |
783 | + | |
784 | +static void | |
785 | +i386_rb_pseudo_register_read (struct gdbarch *gdbarch, | |
786 | + struct regcache *regcache, | |
787 | + int regnum, void *buf) | |
788 | +{ | |
789 | + if (msr_regnum_p (regnum)) | |
790 | + i386_msr_register_read (gdbarch, regcache, regnum, buf); | |
791 | + else | |
792 | + i386_pseudo_register_read (gdbarch, regcache, regnum, buf); | |
793 | +} | |
794 | + | |
795 | +static void | |
796 | +i386_msr_register_write (struct gdbarch *gdbarch, | |
797 | + struct regcache *regcache, int regnum, | |
798 | + const void *buf) | |
799 | +{ | |
800 | + /* ULGH. */ | |
801 | + gdb_assert (msr_regnum_p (regnum)); | |
802 | + if (i386_query_msr_regnum (regnum) == 0) | |
803 | + { | |
804 | + regcache_raw_write (regcache, msr_regnum (), buf); | |
805 | + } | |
806 | +} | |
807 | + | |
808 | +static void | |
809 | +i386_rb_pseudo_register_write (struct gdbarch *gdbarch, | |
810 | + struct regcache *regcache, | |
811 | + int regnum, const void *buf) | |
812 | +{ | |
813 | + if (msr_regnum_p (regnum)) | |
814 | + i386_msr_register_write (gdbarch, regcache, regnum, buf); | |
815 | + else | |
816 | + i386_pseudo_register_write (gdbarch, regcache, regnum, buf); | |
817 | +} | |
818 | + | |
819 | +static void | |
820 | +i386_rb_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) | |
821 | +{ | |
822 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | |
823 | + | |
824 | + /* Red Boot uses ELF. */ | |
825 | + i386_elf_init_abi (info, gdbarch); | |
826 | + | |
827 | + /* We support the SSE registers on Red Boot */ | |
828 | + tdep->num_xmm_regs = I386_NUM_XREGS - 1; | |
829 | + | |
830 | + set_gdbarch_register_bytes (gdbarch, (I386_SSE_SIZEOF_REGS | |
831 | + + num_sys_regs * 4)); | |
832 | + | |
833 | + /* Since we have the extra system and MSR registers, we need to | |
834 | + adjust a few things. */ | |
835 | + | |
836 | + set_gdbarch_num_regs (gdbarch, I386_SSE_NUM_REGS + num_sys_regs); | |
837 | + set_gdbarch_register_name (gdbarch, i386_rb_register_name); | |
838 | + set_gdbarch_register_virtual_type (gdbarch, i386_rb_register_virtual_type); | |
839 | + | |
840 | + set_gdbarch_num_pseudo_regs (gdbarch, NUM_I386_MMX_REGS + num_msr_regs); | |
841 | + set_gdbarch_pseudo_register_read (gdbarch, i386_rb_pseudo_register_read); | |
842 | + set_gdbarch_pseudo_register_write (gdbarch, i386_rb_pseudo_register_write); | |
843 | + | |
844 | + set_gdbarch_next_cooked_register_to_save (gdbarch, i386_rb_next_abi_register); | |
845 | + set_gdbarch_next_cooked_register_to_restore (gdbarch, i386_rb_next_abi_register); | |
846 | + | |
847 | + set_gdbarch_register_reggroup_p (gdbarch, i386_rb_register_regroup_p); | |
848 | + reggroup_add (gdbarch, msr_reggroup); | |
849 | +} | |
850 | + | |
851 | +/* Provide a prototype to silence -Wmissing-prototypes. */ | |
852 | +void _initialize_i386_tdep (void); | |
853 | + | |
854 | +void | |
855 | +_initialize_i386_rb_tdep (void) | |
856 | +{ | |
857 | + /* Ulgh, claim the default. */ | |
858 | + gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_REDBOOT, | |
859 | + i386_rb_init_abi); | |
860 | + | |
861 | + msr_reggroup = reggroup_new ("msr"); | |
862 | +} |
@@ -1097,7 +1097,7 @@ i386_use_struct_convention (int gcc_p, struct type *type) | ||
1097 | 1097 | register REGNUM. Perhaps %esi and %edi should go here, but |
1098 | 1098 | potentially they could be used for things other than address. */ |
1099 | 1099 | |
1100 | -static struct type * | |
1100 | +struct type * | |
1101 | 1101 | i386_register_virtual_type (int regnum) |
1102 | 1102 | { |
1103 | 1103 | if (regnum == PC_REGNUM || regnum == FP_REGNUM || regnum == SP_REGNUM) |
@@ -1132,7 +1132,7 @@ mmx_regnum_to_fp_regnum (struct regcache *regcache, int regnum) | ||
1132 | 1132 | return (FP0_REGNUM + fpi); |
1133 | 1133 | } |
1134 | 1134 | |
1135 | -static void | |
1135 | +void | |
1136 | 1136 | i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, |
1137 | 1137 | int regnum, void *buf) |
1138 | 1138 | { |
@@ -1148,7 +1148,7 @@ i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, | ||
1148 | 1148 | regcache_raw_read (regcache, regnum, buf); |
1149 | 1149 | } |
1150 | 1150 | |
1151 | -static void | |
1151 | +void | |
1152 | 1152 | i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, |
1153 | 1153 | int regnum, const void *buf) |
1154 | 1154 | { |
@@ -1439,7 +1439,7 @@ i386_add_reggroups (struct gdbarch *gdbarch) | ||
1439 | 1439 | reggroup_add (gdbarch, system_reggroup); |
1440 | 1440 | } |
1441 | 1441 | |
1442 | -static int | |
1442 | +int | |
1443 | 1443 | i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum, |
1444 | 1444 | struct reggroup *group) |
1445 | 1445 | { |
@@ -1467,6 +1467,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) | ||
1467 | 1467 | /* Try to determine the OS ABI of the object we're loading. */ |
1468 | 1468 | if (info.abfd != NULL) |
1469 | 1469 | osabi = gdbarch_lookup_osabi (info.abfd); |
1470 | + /* Hack, force redboot. */ | |
1471 | + if (osabi == GDB_OSABI_UNKNOWN) | |
1472 | + osabi = GDB_OSABI_REDBOOT; | |
1470 | 1473 | |
1471 | 1474 | /* Find a candidate among extant architectures. */ |
1472 | 1475 | for (arches = gdbarch_list_lookup_by_info (arches, &info); |
@@ -166,6 +166,19 @@ extern CORE_ADDR i386_pe_skip_trampoline_code (CORE_ADDR pc, char *name); | ||
166 | 166 | /* Return the name of register REG. */ |
167 | 167 | extern char const *i386_register_name (int reg); |
168 | 168 | |
169 | +/* Return the type of the register REG. */ | |
170 | +extern struct type *i386_register_virtual_type (int reg); | |
171 | + | |
172 | +extern void i386_pseudo_register_write (struct gdbarch *gdbarch, | |
173 | + struct regcache *regcache, int regnum, | |
174 | + const void *buf); | |
175 | +extern void i386_pseudo_register_read (struct gdbarch *gdbarch, | |
176 | + struct regcache *regcache, | |
177 | + int regnum, void *buf); | |
178 | + | |
179 | +extern int i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum, | |
180 | + struct reggroup *group); | |
181 | + | |
169 | 182 | /* Initialize a basic ELF architecture variant. */ |
170 | 183 | extern void i386_elf_init_abi (struct gdbarch_info, struct gdbarch *); |
171 | 184 |
@@ -49,6 +49,8 @@ static const char * const gdb_osabi_names[] = | ||
49 | 49 | "ARM EABI v2", |
50 | 50 | "ARM APCS", |
51 | 51 | |
52 | + "RedBoot", | |
53 | + | |
52 | 54 | "<invalid>" |
53 | 55 | }; |
54 | 56 |
@@ -240,7 +242,7 @@ gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch, | ||
240 | 242 | for (handler = gdb_osabi_handler_list; handler != NULL; |
241 | 243 | handler = handler->next) |
242 | 244 | { |
243 | - if (handler->arch == bfd_get_arch (abfd) | |
245 | + if ((abfd == NULL || handler->arch == bfd_get_arch (abfd)) | |
244 | 246 | && handler->osabi == osabi) |
245 | 247 | { |
246 | 248 | (*handler->init_osabi) (info, gdbarch); |
@@ -46,6 +46,8 @@ enum gdb_osabi | ||
46 | 46 | GDB_OSABI_ARM_EABI_V2, |
47 | 47 | GDB_OSABI_ARM_APCS, |
48 | 48 | |
49 | + GDB_OSABI_REDBOOT, | |
50 | + | |
49 | 51 | GDB_OSABI_INVALID /* keep this last */ |
50 | 52 | }; |
51 | 53 |
@@ -273,7 +273,11 @@ init_remote_state (struct gdbarch *gdbarch) | ||
273 | 273 | r->pnum = regnum; |
274 | 274 | r->regnum = regnum; |
275 | 275 | r->offset = REGISTER_BYTE (regnum); |
276 | +#ifdef GPACKET_UPPER_BOUND_HACK | |
277 | + r->in_g_packet = (regnum < GPACKET_UPPER_BOUND_HACK (gdbarch)); | |
278 | +#else | |
276 | 279 | r->in_g_packet = (regnum < NUM_REGS); |
280 | +#endif | |
277 | 281 | /* ...size = REGISTER_RAW_SIZE (regnum); */ |
278 | 282 | /* ...name = REGISTER_NAME (regnum); */ |
279 | 283 | } |
@@ -3416,6 +3420,65 @@ got_status: | ||
3416 | 3420 | |
3417 | 3421 | static int register_bytes_found; |
3418 | 3422 | |
3423 | +/* Helper for remote_fetch_registers. Fetch a register using the | |
3424 | + ``p'' packet. */ | |
3425 | + | |
3426 | +static void | |
3427 | +fetch_register_using_p (int regnum) | |
3428 | +{ | |
3429 | + struct remote_state *rs = get_remote_state (); | |
3430 | + char *regs; | |
3431 | + char *buf; | |
3432 | + int i; | |
3433 | + char *p; | |
3434 | + | |
3435 | + buf = alloca (rs->remote_packet_size); | |
3436 | + sprintf (buf, "p%x", regnum); | |
3437 | + remote_send (buf, rs->remote_packet_size); | |
3438 | + | |
3439 | + /* We can get out of synch in various cases. If the first character | |
3440 | + in the buffer is not a hex character, assume that has happened | |
3441 | + and try to fetch another packet to read. */ | |
3442 | + while ((buf[0] < '0' || buf[0] > '9') | |
3443 | + && (buf[0] < 'a' || buf[0] > 'f') | |
3444 | + && buf[0] != 'x') /* New: unavailable register value */ | |
3445 | + { | |
3446 | + if (remote_debug) | |
3447 | + fprintf_unfiltered (gdb_stdlog, | |
3448 | + "Bad register packet; fetching a new packet\n"); | |
3449 | + getpkt (buf, rs->remote_packet_size, 0); | |
3450 | + } | |
3451 | + | |
3452 | + /* Reply describes registers byte by byte, each byte encoded as two | |
3453 | + hex characters. Suck them all up, then supply them to the | |
3454 | + register cacheing/storage mechanism. */ | |
3455 | + | |
3456 | + regs = alloca (REGISTER_RAW_SIZE (regnum)); | |
3457 | + memset (regs, REGISTER_RAW_SIZE (regnum), 0); | |
3458 | + p = buf; | |
3459 | + for (i = 0; i < REGISTER_RAW_SIZE (regnum); i++) | |
3460 | + { | |
3461 | + if (p[0] == 0) | |
3462 | + break; | |
3463 | + if (p[1] == 0) | |
3464 | + { | |
3465 | + warning ("Remote reply is of odd length: %s", buf); | |
3466 | + /* Don't change register_bytes_found in this case, and don't | |
3467 | + print a second warning. */ | |
3468 | + break; | |
3469 | + } | |
3470 | + if (p[0] == 'x' && p[1] == 'x') | |
3471 | + regs[i] = 0; /* 'x' */ | |
3472 | + else | |
3473 | + regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]); | |
3474 | + p += 2; | |
3475 | + } | |
3476 | + | |
3477 | + supply_register (regnum, ®s[0]); | |
3478 | + if (buf[0] == 'x') | |
3479 | + register_valid[i] = -1; /* register value not available */ | |
3480 | +} | |
3481 | + | |
3419 | 3482 | /* Read the remote registers into the block REGS. */ |
3420 | 3483 | /* Currently we just read all the registers, so we don't use regnum. */ |
3421 | 3484 |
@@ -3435,10 +3498,18 @@ remote_fetch_registers (int regnum) | ||
3435 | 3498 | { |
3436 | 3499 | struct packet_reg *reg = packet_reg_from_regnum (rs, regnum); |
3437 | 3500 | gdb_assert (reg != NULL); |
3501 | +#if 1 | |
3502 | + if (!reg->in_g_packet) | |
3503 | + { | |
3504 | + fetch_register_using_p (regnum); | |
3505 | + return; | |
3506 | + } | |
3507 | +#else | |
3438 | 3508 | if (!reg->in_g_packet) |
3439 | 3509 | internal_error (__FILE__, __LINE__, |
3440 | 3510 | "Attempt to fetch a non G-packet register when this " |
3441 | 3511 | "remote.c does not support the p-packet."); |
3512 | +#endif | |
3442 | 3513 | } |
3443 | 3514 | |
3444 | 3515 | sprintf (buf, "g"); |