* command.c (shell_escape, make_command, _initialze_command):
[deliverable/binutils-gdb.git] / gdb / hppab-tdep.c
CommitLineData
fb1415ae
JG
1/* Machine-dependent code which would otherwise be in inflow.c and core.c,
2 for GDB, the GNU debugger. This code is for the HP PA-RISC cpu.
3 Copyright 1986, 1987, 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
4
5 Contributed by the Center for Software Science at the
6 University of Utah (pa-gdb-bugs@cs.utah.edu).
7
8This file is part of GDB.
9
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2 of the License, or
13(at your option) any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
23
24#include "defs.h"
25#include "frame.h"
26#include "inferior.h"
27#include "value.h"
28
29/* For argument passing to the inferior */
30#include "symtab.h"
31
32#ifdef USG
33#include <sys/types.h>
34#endif
35
36#include <sys/param.h>
37#include <sys/dir.h>
38#include <signal.h>
39#include <sys/ioctl.h>
40
41#ifdef COFF_ENCAPSULATE
42#include "a.out.encap.h"
43#else
44#include <a.out.h>
45#endif
46#ifndef N_SET_MAGIC
47#define N_SET_MAGIC(exec, val) ((exec).a_magic = (val))
48#endif
49
50/*#include <sys/user.h> After a.out.h */
51#include <sys/file.h>
52#include <sys/stat.h>
fb1415ae
JG
53#include <machine/psl.h>
54
55#ifdef KERNELDEBUG
56#include <sys/vmmac.h>
57#include <machine/machparam.h>
58#include <machine/vmparam.h>
59#include <machine/pde.h>
60#include <machine/cpu.h>
61#include <machine/iomod.h>
62#include <machine/pcb.h>
63#include <machine/rpb.h>
64#include <ctype.h>
65
66extern int kernel_debugging;
67extern CORE_ADDR startup_file_start;
68extern CORE_ADDR startup_file_end;
69
70#define KERNOFF ((unsigned)KERNBASE)
71#define INKERNEL(x) ((x) >= KERNOFF && (x) < KERNOFF + ctob(slr))
72
73static int ok_to_cache();
74static void set_kernel_boundaries();
75
76int devmem = 0;
77int vtophys_ready = 0;
78int kerneltype;
79#define OS_BSD 1
80#define OS_MACH 2
81#endif
82
83#include "gdbcore.h"
84#include "gdbcmd.h"
85
86extern int errno;
87\f
88
89
90
91
92
93/* Last modification time of executable file.
94 Also used in source.c to compare against mtime of a source file. */
95
96extern int exec_mtime;
97
98/* Virtual addresses of bounds of the two areas of memory in the core file. */
99
100/* extern CORE_ADDR data_start; */
101extern CORE_ADDR data_end;
102extern CORE_ADDR stack_start;
103extern CORE_ADDR stack_end;
104
105/* Virtual addresses of bounds of two areas of memory in the exec file.
106 Note that the data area in the exec file is used only when there is no core file. */
107
108extern CORE_ADDR text_start;
109extern CORE_ADDR text_end;
110
111extern CORE_ADDR exec_data_start;
112extern CORE_ADDR exec_data_end;
113
114/* Address in executable file of start of text area data. */
115
116extern int text_offset;
117
118/* Address in executable file of start of data area data. */
119
120extern int exec_data_offset;
121
122/* Address in core file of start of data area data. */
123
124extern int data_offset;
125
126/* Address in core file of start of stack area data. */
127
128extern int stack_offset;
129
130struct header file_hdr;
131struct som_exec_auxhdr exec_hdr;
132\f
133#ifdef KERNELDEBUG
134/*
135 * Kernel debugging routines.
136 */
137
138static struct pcb pcb;
139static struct pde *pdir;
140static struct hte *htbl;
141static u_int npdir, nhtbl;
142
143static CORE_ADDR
144ksym_lookup(name)
145 char *name;
146{
147 struct symbol *sym;
148 int i;
149
150 if ((i = lookup_misc_func(name)) < 0)
151 error("kernel symbol `%s' not found.", name);
152
153 return (misc_function_vector[i].address);
154}
155
156/*
157 * (re-)set the variables that tell "inside_entry_file" where to end
158 * a stack backtrace.
159 */
160void
161set_kernel_boundaries()
162{
163 switch (kerneltype) {
164 case OS_MACH:
165 startup_file_start = ksym_lookup("$syscall");
166 startup_file_end = ksym_lookup("trap");
167 break;
168 case OS_BSD:
169 startup_file_start = ksym_lookup("syscallinit");
170 startup_file_end = ksym_lookup("$syscallexit");
171 break;
172 }
173}
174
175/*
176 * return true if 'len' bytes starting at 'addr' can be read out as
177 * longwords and/or locally cached (this is mostly for memory mapped
178 * i/o register access when debugging remote kernels).
179 */
180static int
181ok_to_cache(addr, len)
182{
183 static CORE_ADDR ioptr;
184
185 if (! ioptr)
186 ioptr = ksym_lookup("ioptr");
187
188 if (addr >= ioptr && addr < SPA_HIGH)
189 return (0);
190
191 return (1);
192}
193
194static
195physrd(addr, dat, len)
196 u_int addr;
197 char *dat;
198{
199 if (lseek(corechan, addr, L_SET) == -1)
200 return (-1);
201 if (read(corechan, dat, len) != len)
202 return (-1);
203
204 return (0);
205}
206
207/*
208 * When looking at kernel data space through /dev/mem or with a core file, do
209 * virtual memory mapping.
210 */
211static CORE_ADDR
212vtophys(space, addr)
213 unsigned space;
214 CORE_ADDR addr;
215{
216 struct pde *pptr;
217 u_int hindx, vpageno, ppageno;
218 CORE_ADDR phys = ~0;
219
220 if (!vtophys_ready) {
221 phys = addr; /* XXX for kvread */
222 } else if (kerneltype == OS_BSD) {
223 /* make offset into a virtual page no */
224 vpageno = btop(addr);
225 /*
226 * Determine index into hash table, initialize pptr to this
227 * entry (since first word of pte & hte are same), and set
228 * physical page number for first entry in chain.
229 */
230 hindx = pdirhash(space, addr) & (nhtbl-1);
231 pptr = (struct pde *) &htbl[hindx];
232 ppageno = pptr->pde_next;
233 while (1) {
234 if (pptr->pde_end)
235 break;
236 pptr = &pdir[ppageno];
237 /*
238 * If space id & virtual page number match, return
239 * "next PDIR entry of previous PDIR entry" as the
240 * physical page or'd with offset into page.
241 */
242 if (pptr->pde_space == space &&
243 pptr->pde_page == vpageno) {
244 phys = (CORE_ADDR) ((u_int)ptob(ppageno) |
245 (addr & PGOFSET));
246 break;
247 }
248 ppageno = pptr->pde_next;
249 }
250 }
251#ifdef MACHKERNELDEBUG
252 else if (kerneltype == OS_MACH) {
253 mach_vtophys(space, addr, &phys);
254 }
255#endif
256#if 0
257 printf("vtophys(%x.%x) -> %x\n", space, addr, phys);
258#endif
259 return (phys);
260}
261
262static
263kvread(addr)
264 CORE_ADDR addr;
265{
266 CORE_ADDR paddr;
267
268 paddr = vtophys(0, addr);
269 if (paddr != ~0)
270 if (physrd(paddr, (char *)&addr, sizeof(addr)) == 0)
271 return (addr);
272
273 return (~0);
274}
275
276static void
277read_pcb(addr)
278 u_int addr;
279{
280 int i, off;
281 extern char registers[];
282 static int reg2pcb[] = {
283 /* RPB */
284 -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
285 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
286 45, 52, 51, 75, 74, 49, 53, 54, 55, 56, -1, 70, 66, 67, 68, 69,
287 71, 72, 73, 34, 42, 43, 44, 46, 47, 58, 59, 60, -1, -1, -1, -1,
288 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
289 -1, -1, -1, -1,
290 /* BSD */
291 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
292 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
293 43, 64, 67, 68, 67, 47, 51, 52, 53, 54, -1, 35, 31, 32, 33, 34,
294 36, 37, 38, 39, 40, 41, 42, 44, 45, 56, 57, 58,102,103,104, -1,
295 70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 82, 84, 86, 88, 90, 92,
296 94, 96, 98, 100,
297 /* Mach */
298 -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
299 14, 15, 16, -1, -1, -1, -1, -1, -1, -1, -1, 17, -1, -1, 18, -1,
300 25, -1, -1, -1, -1, 30, -1, -1, -1, -1, -1, 20, -1, -1, -1, 19,
301 21, 22, 23, 24, 26, 27, -1, 28, 29, -1, -1, -1, -1, -1, -1, -1,
302 34, 35, 36, 37, 38, 39, 40, 41, -1, -1, -1, -1, -1, -1, -1, -1,
303 42, 44, 46, 48
304 };
305 static struct rpb *rpbaddr = (struct rpb *) 0;
306 static u_int rpbpcbaddr = 0;
307
308 if (!remote_debugging) {
309 /*
310 * If we are debugging a post-mortem and this is the first
311 * call of read_pcb, read the RPB. Also assoicate the
312 * thread/proc running at the time with the RPB.
313 */
314 if (!devmem && rpbpcbaddr == 0) {
315 CORE_ADDR raddr = ksym_lookup("rpb");
316 int usepcb = 1;
317
318 if (raddr != ~0) {
319 rpbaddr = (struct rpb *) malloc(sizeof *rpbaddr);
320 if (!physrd(raddr, (char *)rpbaddr, sizeof *rpbaddr)) {
321 rpbpcbaddr = addr;
322 usepcb = 0;
323 }
324 }
325 if (usepcb) {
326 error("cannot read rpb, using pcb for registers\n");
327 if (rpbaddr)
328 free((char *)rpbaddr);
329 rpbpcbaddr = ~0;
330 }
331 }
332 if (physrd (addr, (char *)&pcb, sizeof pcb))
333 error ("cannot read pcb at %x.\n", addr);
334 } else {
335 if (remote_read_inferior_memory(addr, (char *)&pcb, sizeof pcb))
336 error ("cannot read pcb at %x.\n", addr);
337 }
338
339 if (kerneltype == OS_BSD) {
340 printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n",
341 pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr);
342 off = NUM_REGS;
343 } else {
344 printf("pcb %lx psw %lx ksp %lx\n",
345 addr, ((int *)&pcb)[31], ((int *)&pcb)[32]);
346 off = NUM_REGS * 2;
347 }
348 /*
349 * get the register values out of the sys pcb and
350 * store them where `read_register' will find them.
351 */
352 bzero(registers, REGISTER_BYTES);
353 for (i = 0; i < NUM_REGS; ++i)
354 if (reg2pcb[i+off] != -1)
355 supply_register(i, &((int *)&pcb)[reg2pcb[i+off]]);
356 /*
357 * If the RPB is valid for this thread/proc use the register values
358 * contained there.
359 */
360 if (addr == rpbpcbaddr) {
361 off = 0;
362 for (i = 0; i < NUM_REGS; ++i)
363 if (reg2pcb[i+off] != -1)
364 supply_register(i, &((int *)rpbaddr)[reg2pcb[i+off]]);
365 }
366}
367
368void
369setup_kernel_debugging()
370{
371 struct stat stb;
372 CORE_ADDR addr;
373
374 fstat(corechan, &stb);
375 devmem = 0;
376 if ((stb.st_mode & S_IFMT) == S_IFCHR && stb.st_rdev == makedev(2, 0))
377 devmem = 1;
378
379 /* XXX */
380 if (lookup_misc_func("Sysmap") < 0)
381 kerneltype = OS_MACH;
382 else
383 kerneltype = OS_BSD;
384
385 if (kerneltype == OS_BSD) {
386 int len, err = 0;
387
388 /*
389 * Hash table and PDIR are equivalently mapped
390 */
391 nhtbl = kvread(ksym_lookup("nhtbl"));
392 if (nhtbl != ~0) {
393 len = nhtbl * sizeof(*htbl);
394 htbl = (struct hte *) malloc(len);
395 if (htbl) {
396 addr = kvread(ksym_lookup("htbl"));
397 if (physrd(addr, (char *)htbl, len))
398 err++;
399 } else
400 err++;
401 } else
402 err++;
403 npdir = kvread(ksym_lookup("npdir"));
404 if (npdir != ~0) {
405 len = npdir * sizeof(*pdir);
406 pdir = (struct pde *) malloc(len);
407 if (pdir) {
408 addr = kvread(ksym_lookup("pdir"));
409 if (physrd(addr, (char *)pdir, len))
410 err++;
411 } else
412 err++;
413 } else
414 err++;
415 if (err) {
416 error("cannot read PDIR/HTBL");
417 return;
418 }
419 vtophys_ready = 1;
420
421 /*
422 * pcb where "panic" saved registers in first thing in
423 * current u-area. The current u-area is pointed to by
424 * "uptr".
425 */
426 addr = kvread(ksym_lookup("uptr"));
427 if (addr == ~0) {
428 error("cannot read current u-area address");
429 return;
430 }
431 read_pcb(vtophys(0, addr)); /* XXX space */
432 if (!devmem) {
433 /* find stack frame */
434 CORE_ADDR panicstr;
435 char buf[256];
436 register char *cp;
437
438 panicstr = kvread(ksym_lookup("panicstr"));
439 if (panicstr == ~0)
440 return;
441 kernel_core_file_hook(panicstr, buf, sizeof(buf));
442 for (cp = buf; cp < &buf[sizeof(buf)] && *cp; cp++)
443 if (!isascii(*cp) || (!isprint(*cp) && !isspace(*cp)))
444 *cp = '?';
445 if (*cp)
446 *cp = '\0';
447 printf("panic: %s\n", buf);
448 }
449 }
450#ifdef MACHKERNELDEBUG
451 else {
452 int *thread;
453
454 /*
455 * Set up address translation
456 */
457 if (mach_vtophys_init() == 0) {
458 error("cannot initialize vtophys for Mach");
459 return;
460 }
461 vtophys_ready = 1;
462
463 /*
464 * Locate active thread and read PCB
465 * XXX MAJOR HACK
466 * - assumes uni-processor
467 * - assumes position of pcb to avoid mach includes
468 */
469 thread = (int *)kvread(ksym_lookup("active_threads"));
470 addr = kvread(&thread[9]); /* XXX: pcb addr */
471 read_pcb(vtophys(0, addr));
472 }
473#endif
474}
475
476vtop_command(arg)
477 char *arg;
478{
479 u_int sp, off, pa;
480
481 if (!arg)
482 error_no_arg("kernel virtual address");
483 if (!kernel_debugging)
484 error("not debugging kernel");
485
486 sp = 0; /* XXX */
487 off = (u_int) parse_and_eval_address(arg);
488 pa = vtophys(sp, off);
489 printf("%lx.%lx -> ", sp, off);
490 if (pa == ~0)
491 printf("<invalid>\n");
492 else
493 printf("%lx\n", pa);
494}
495
496set_paddr_command(arg)
497 char *arg;
498{
499 u_int addr;
500
501 if (!arg) {
502 if (kerneltype == OS_BSD)
503 error_no_arg("ps-style address for new process");
504 else
505 error_no_arg("thread structure virtual address");
506 }
507 if (!kernel_debugging)
508 error("not debugging kernel");
509
510 addr = (u_int) parse_and_eval_address(arg);
511 if (kerneltype == OS_BSD)
512 addr = ctob(addr);
513 else {
514 addr = kvread(&(((int *)addr)[9])); /* XXX: pcb addr */
515 addr = vtophys(0, addr); /* XXX space */
516 }
517 read_pcb(addr);
518
519 flush_cached_frames();
520 set_current_frame(create_new_frame(read_register(FP_REGNUM), read_pc()));
521 select_frame(get_current_frame(), 0);
522}
523
524/*
525 * read len bytes from kernel virtual address 'addr' into local
526 * buffer 'buf'. Return 0 if read ok, 1 otherwise. On read
527 * errors, portion of buffer not read is zeroed.
528 */
529kernel_core_file_hook(addr, buf, len)
530 CORE_ADDR addr;
531 char *buf;
532 int len;
533{
534 int i;
535 CORE_ADDR paddr;
536
537 while (len > 0) {
538 paddr = vtophys(0, addr); /* XXX space */
539 if (paddr == ~0) {
540 bzero(buf, len);
541 return (1);
542 }
543 /* we can't read across a page boundary */
544 i = min(len, NBPG - (addr & PGOFSET));
545 if (physrd(paddr, buf, i)) {
546 bzero(buf, len);
547 return (1);
548 }
549 buf += i;
550 addr += i;
551 len -= i;
552 }
553 return (0);
554}
555#endif
556
557
558\f
559
560
561/* Routines to extract various sized constants out of hppa
562 instructions. */
563
564/* This assumes that no garbage lies outside of the lower bits of
565 value. */
566
567int
568sign_extend (val, bits)
569 unsigned val, bits;
570{
571 return (int)(val >> bits - 1 ? (-1 << bits) | val : val);
572}
573
574/* For many immediate values the sign bit is the low bit! */
575
576int
577low_sign_extend (val, bits)
578 unsigned val, bits;
579{
580 return (int)((val & 0x1 ? (-1 << (bits - 1)) : 0) | val >> 1);
581}
582/* extract the immediate field from a ld{bhw}s instruction */
583
584
585
586unsigned
587get_field (val, from, to)
588 unsigned val, from, to;
589{
590 val = val >> 31 - to;
591 return val & ((1 << 32 - from) - 1);
592}
593
594unsigned
595set_field (val, from, to, new_val)
596 unsigned *val, from, to;
597{
598 unsigned mask = ~((1 << (to - from + 1)) << (31 - from));
599 return *val = *val & mask | (new_val << (31 - from));
600}
601
602/* extract a 3-bit space register number from a be, ble, mtsp or mfsp */
603
604extract_3 (word)
605 unsigned word;
606{
607 return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);
608}
609
610extract_5_load (word)
611 unsigned word;
612{
613 return low_sign_extend (word >> 16 & MASK_5, 5);
614}
615
616/* extract the immediate field from a st{bhw}s instruction */
617
618int
619extract_5_store (word)
620 unsigned word;
621{
622 return low_sign_extend (word & MASK_5, 5);
623}
624
625/* extract an 11 bit immediate field */
626
627int
628extract_11 (word)
629 unsigned word;
630{
631 return low_sign_extend (word & MASK_11, 11);
632}
633
634/* extract a 14 bit immediate field */
635
636int
637extract_14 (word)
638 unsigned word;
639{
640 return low_sign_extend (word & MASK_14, 14);
641}
642
643/* deposit a 14 bit constant in a word */
644
645unsigned
646deposit_14 (opnd, word)
647 int opnd;
648 unsigned word;
649{
650 unsigned sign = (opnd < 0 ? 1 : 0);
651
652 return word | ((unsigned)opnd << 1 & MASK_14) | sign;
653}
654
655/* extract a 21 bit constant */
656
657int
658extract_21 (word)
659 unsigned word;
660{
661 int val;
662
663 word &= MASK_21;
664 word <<= 11;
665 val = GET_FIELD (word, 20, 20);
666 val <<= 11;
667 val |= GET_FIELD (word, 9, 19);
668 val <<= 2;
669 val |= GET_FIELD (word, 5, 6);
670 val <<= 5;
671 val |= GET_FIELD (word, 0, 4);
672 val <<= 2;
673 val |= GET_FIELD (word, 7, 8);
674 return sign_extend (val, 21) << 11;
675}
676
677/* deposit a 21 bit constant in a word. Although 21 bit constants are
678 usually the top 21 bits of a 32 bit constant, we assume that only
679 the low 21 bits of opnd are relevant */
680
681unsigned
682deposit_21 (opnd, word)
683 unsigned opnd, word;
684{
685 unsigned val = 0;
686
687 val |= GET_FIELD (opnd, 11 + 14, 11 + 18);
688 val <<= 2;
689 val |= GET_FIELD (opnd, 11 + 12, 11 + 13);
690 val <<= 2;
691 val |= GET_FIELD (opnd, 11 + 19, 11 + 20);
692 val <<= 11;
693 val |= GET_FIELD (opnd, 11 + 1, 11 + 11);
694 val <<= 1;
695 val |= GET_FIELD (opnd, 11 + 0, 11 + 0);
696 return word | val;
697}
698
699/* extract a 12 bit constant from branch instructions */
700
701int
702extract_12 (word)
703 unsigned word;
704{
705 return sign_extend (GET_FIELD (word, 19, 28) |
706 GET_FIELD (word, 29, 29) << 10 |
707 (word & 0x1) << 11, 12) << 2;
708}
709
710/* extract a 17 bit constant from branch instructions, returning the
711 19 bit signed value. */
712
713int
714extract_17 (word)
715 unsigned word;
716{
717 return sign_extend (GET_FIELD (word, 19, 28) |
718 GET_FIELD (word, 29, 29) << 10 |
719 GET_FIELD (word, 11, 15) << 11 |
720 (word & 0x1) << 16, 17) << 2;
721}
722
723
724CORE_ADDR
725frame_saved_pc (frame)
726 FRAME frame;
727{
728 if (get_current_frame () == frame)
729 {
730 struct frame_saved_regs saved_regs;
731
732 get_frame_saved_regs (frame, &saved_regs);
733 if (saved_regs.regs[RP_REGNUM])
734 return read_memory_integer (saved_regs.regs[RP_REGNUM], 4);
735 else
736 return read_register (RP_REGNUM);
737 }
738 return read_memory_integer (frame->frame - 20, 4) & ~0x3;
739}
740
741/* To see if a frame chain is valid, see if the caller looks like it
742 was compiled with gcc. */
743
744int frame_chain_valid (chain, thisframe)
745 FRAME_ADDR chain;
746 FRAME thisframe;
747{
748 if (chain && (chain > 0x60000000
749 /* || remote_debugging -this is no longer used */
750#ifdef KERNELDEBUG
751 || kernel_debugging
752#endif
753 ))
754 {
755 CORE_ADDR pc = get_pc_function_start (FRAME_SAVED_PC (thisframe));
756
757 if (!inside_entry_file (pc))
758 return 0;
759 /* look for stw rp, -20(0,sp); copy 4,1; copy sp, 4 */
760 if (read_memory_integer (pc, 4) == 0x6BC23FD9)
761 pc = pc + 4;
762
763 if (read_memory_integer (pc, 4) == 0x8040241 &&
764 read_memory_integer (pc + 4, 4) == 0x81E0244)
765 return 1;
766 else
767 return 0;
768 }
769 else
770 return 0;
771}
772
773/* Some helper functions. gcc_p returns 1 if the function beginning at
774 pc appears to have been compiled with gcc. hpux_cc_p returns 1 if
775 fn was compiled with hpux cc. gcc functions look like :
776
777 stw rp,-0x14(sp) ; optional
778 or r4,r0,r1
779 or sp,r0,r4
780 stwm r1,framesize(sp)
781
782 hpux cc functions look like:
783
784 stw rp,-0x14(sp) ; optional.
785 stwm r3,framesiz(sp)
786 */
787
788gcc_p (pc)
789 CORE_ADDR pc;
790{
791 if (read_memory_integer (pc, 4) == 0x6BC23FD9)
792 pc = pc + 4;
793
794 if (read_memory_integer (pc, 4) == 0x8040241 &&
795 read_memory_integer (pc + 4, 4) == 0x81E0244)
796 return 1;
797 return 0;
798}
799
800
801find_dummy_frame_regs (frame, frame_saved_regs)
802 struct frame_info *frame;
803 struct frame_saved_regs *frame_saved_regs;
804{
805 CORE_ADDR fp = frame->frame;
806 int i;
807
808 frame_saved_regs->regs[RP_REGNUM] = fp - 20 & ~0x3;
809 frame_saved_regs->regs[FP_REGNUM] = fp;
810 frame_saved_regs->regs[1] = fp + 8;
811 frame_saved_regs->regs[3] = fp + 12;
812 for (fp += 16, i = 3; i < 30; fp += 4, i++)
813 frame_saved_regs->regs[i] = fp;
814 frame_saved_regs->regs[31] = fp;
815 fp += 4;
816 for (i = FP0_REGNUM; i < NUM_REGS; i++, fp += 8)
817 frame_saved_regs->regs[i] = fp;
818 /* depend on last increment of fp */
819 frame_saved_regs->regs[IPSW_REGNUM] = fp - 4;
820 frame_saved_regs->regs[SAR_REGNUM] = fp;
821 fp += 4;
822 frame_saved_regs->regs[PCOQ_TAIL_REGNUM] = fp;
823 frame_saved_regs->regs[PCSQ_TAIL_REGNUM] = fp;
824}
825
826CORE_ADDR
827hp_push_arguments (nargs, args, sp, struct_return, struct_addr)
828 int nargs;
829 value *args;
830 CORE_ADDR sp;
831 int struct_return;
832 CORE_ADDR struct_addr;
833{
834 /* array of arguments' offsets */
835 int *offset = (int *)alloca(nargs);
836 int cum = 0;
837 int i, alignment;
838
839 for (i = 0; i < nargs; i++)
840 {
841 cum += TYPE_LENGTH (VALUE_TYPE (args[i]));
842 /* value must go at proper alignment. Assume alignment is a
843 power of two.*/
844 alignment = hp_alignof (VALUE_TYPE (args[i]));
845 if (cum % alignment)
846 cum = (cum + alignment) & -alignment;
847 offset[i] = -cum;
848 }
849 for (i == 0; i < nargs; i++)
850 {
851 write_memory (sp + offset[i], VALUE_CONTENTS (args[i]), sizeof(int));
852 }
853 sp += min ((cum + 7) & -8, 48);
854 if (struct_return)
855 write_register (28, struct_addr);
856 return sp + 48;
857}
858
859/* return the alignment of a type in bytes. Structures have the maximum
860 alignment required by their fields. */
861
862int
863hp_alignof (arg)
864 struct type *arg;
865{
866 int max_align, align, i;
867 switch (TYPE_CODE (arg))
868 {
869 case TYPE_CODE_PTR:
870 case TYPE_CODE_INT:
871 case TYPE_CODE_FLT:
872 return TYPE_LENGTH (arg);
873 case TYPE_CODE_ARRAY:
874 return hp_alignof (TYPE_FIELD_TYPE (arg, 0));
875 case TYPE_CODE_STRUCT:
876 case TYPE_CODE_UNION:
877 max_align = 2;
878 for (i = 0; i < TYPE_NFIELDS (arg); i++)
879 {
880 /* Bit fields have no real alignment. */
881 if (!TYPE_FIELD_BITPOS (arg, i))
882 {
883 align = hp_alignof (TYPE_FIELD_TYPE (arg, i));
884 max_align = max (max_align, align);
885 }
886 }
887 return max_align;
888 default:
889 return 4;
890 }
891}
892
893/* Print the register regnum, or all registers if regnum is -1 */
894
895pa_do_registers_info (regnum, fpregs)
896 int regnum;
897 int fpregs;
898{
899 char raw_regs [REGISTER_BYTES];
900 int i;
901
902 for (i = 0; i < NUM_REGS; i++)
903 read_relative_register_raw_bytes (i, raw_regs + REGISTER_BYTE (i));
904 if (regnum = -1)
905 pa_print_registers (raw_regs, regnum);
906 else if (regnum < FP0_REGNUM)
907 {
908 printf ("%s %x\n", reg_names[regnum], *(long *)(raw_regs +
909 REGISTER_BYTE (regnum)));
910 }
911 else
912 pa_print_fp_reg (regnum);
913}
914
915pa_print_registers (raw_regs, regnum)
916 char *raw_regs;
917 int regnum;
918{
919 int i;
920
921 for (i = 0; i < 18; i++)
922 printf ("%8.8s: %8x %8.8s: %8x %8.8s: %8x %8.8s: %8x\n",
923 reg_names[i],
924 *(int *)(raw_regs + REGISTER_BYTE (i)),
925 reg_names[i + 18],
926 *(int *)(raw_regs + REGISTER_BYTE (i + 18)),
927 reg_names[i + 36],
928 *(int *)(raw_regs + REGISTER_BYTE (i + 36)),
929 reg_names[i + 54],
930 *(int *)(raw_regs + REGISTER_BYTE (i + 54)));
931 for (i = 72; i < NUM_REGS; i++)
932 pa_print_fp_reg (i);
933}
934
935pa_print_fp_reg (i)
936 int i;
937{
938 unsigned char raw_buffer[MAX_REGISTER_RAW_SIZE];
939 unsigned char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
940 REGISTER_TYPE val;
941
942 /* Get the data in raw format, then convert also to virtual format. */
943 read_relative_register_raw_bytes (i, raw_buffer);
944 REGISTER_CONVERT_TO_VIRTUAL (i, raw_buffer, virtual_buffer);
945
946 fputs_filtered (reg_names[i], stdout);
947 print_spaces_filtered (15 - strlen (reg_names[i]), stdout);
948
949 val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, stdout, 0,
950 1, 0, Val_pretty_default);
951 printf_filtered ("\n");
952
953}
954
955/*
956 * Virtual to physical translation routines for Utah's Mach 3.0
957 */
958#ifdef MACHKERNELDEBUG
959
960#define STATIC
961
962#if 0 /* too many includes to resolve, too much crap */
963#include <kern/queue.h>
964#include <vm/pmap.h>
965#include <mach/vm_prot.h>
966#else
967/* queue.h */
968struct queue_entry {
969 struct queue_entry *next; /* next element */
970 struct queue_entry *prev; /* previous element */
971};
972
973typedef struct queue_entry *queue_t;
974typedef struct queue_entry queue_head_t;
975typedef struct queue_entry queue_chain_t;
976typedef struct queue_entry *queue_entry_t;
977
978/* pmap.h */
979#define HP800_HASHSIZE 1024
980#define HP800_HASHSIZE_LOG2 10
981
982#define pmap_hash(space, offset) \
983 (((unsigned) (space) << 5 ^ \
984 ((unsigned) (offset) >> 19 | (unsigned) (space) << 13) ^ \
985 (unsigned) (offset) >> 11) & (HP800_HASHSIZE-1))
986
987struct mapping {
988 queue_head_t hash_link; /* hash table links */
989 queue_head_t phys_link; /* for mappings of a given PA */
990 space_t space; /* virtual space */
991 unsigned offset; /* virtual page number */
992 unsigned tlbpage; /* physical page (for TLB load) */
993 unsigned tlbprot; /* prot/access rights (for TLB load) */
994 struct pmap *pmap; /* pmap mapping belongs to */
995};
996
997struct phys_entry {
998 queue_head_t phys_link; /* head of mappings of a given PA */
999 struct mapping *writer; /* mapping with R/W access */
1000 unsigned tlbprot; /* TLB format protection */
1001};
1002
1003#endif
1004
1005#define atop(a) ((unsigned)(a) >> 11)
1006#define ptoa(p) ((unsigned)(p) << 11)
1007#define trunc_page(a) ((unsigned)(a) & ~2047)
1008
1009STATIC long equiv_end;
1010STATIC queue_head_t *Ovtop_table, *vtop_table, *Ofree_mapping, free_mapping;
1011STATIC struct phys_entry *Ophys_table, *phys_table;
1012STATIC long vm_last_phys, vm_first_phys;
1013STATIC struct mapping *firstmap, *lastmap, *Omap_table, *map_table;
1014STATIC unsigned Omlow, Omhigh, Omhead, Ovlow, Ovhigh, Oplow, Ophigh;
1015STATIC unsigned mlow, mhigh, mhead, vlow, vhigh, plow, phigh;
1016STATIC int vtopsize, physsize, mapsize;
1017STATIC int kmemfd;
1018
1019#define IS_OVTOPPTR(p) ((unsigned)(p) >= Ovlow && (unsigned)(p) < Ovhigh)
1020#define IS_OMAPPTR(p) ((unsigned)(p) >= Omlow && (unsigned)(p) < Omhigh)
1021#define IS_OPHYSPTR(p) ((unsigned)(p) >= Oplow && (unsigned)(p) < Ophigh)
1022#define IS_VTOPPTR(p) ((unsigned)(p) >= vlow && (unsigned)(p) < vhigh)
1023#define IS_MAPPTR(p) ((unsigned)(p) >= mlow && (unsigned)(p) < mhigh)
1024#define IS_PHYSPTR(p) ((unsigned)(p) >= plow && (unsigned)(p) < phigh)
1025
1026struct mapstate {
1027 char unused;
1028 char flags;
1029 short hashix;
1030 short physix;
1031} *mapstate;
1032
1033/* flags */
1034#define M_ISFREE 1
1035#define M_ISHASH 2
1036#define M_ISPHYS 4
1037
1038mach_vtophys_init()
1039{
1040 int errors = 0;
1041
1042 if (!readdata())
1043 errors++;
1044 if (!verifydata())
1045 errors++;
1046 if (!errors)
1047 return(1);
1048 fflush(stdout);
1049 fprintf(stderr,
1050 "translate: may not be able to translate all addresses\n");
1051 return(0);
1052}
1053
1054mach_vtophys(space, off, pa)
1055 unsigned space, off, *pa;
1056{
1057 register int i;
1058 register queue_t qp;
1059 register struct mapping *mp;
1060 int poff;
1061
1062 /*
1063 * Kernel IO or equivilently mapped, one to one.
1064 */
1065 if (space == 0 && (long)off < equiv_end) {
1066 *pa = off;
1067 return(1);
1068 }
1069 /*
1070 * Else look it up in specified space
1071 */
1072 poff = off - trunc_page(off);
1073 off = trunc_page(off);
1074 qp = &vtop_table[pmap_hash(space, off)];
1075 for (mp = (struct mapping *)qp->next;
1076 qp != (queue_entry_t)mp;
1077 mp = (struct mapping *)mp->hash_link.next) {
1078 if (mp->space == space && mp->offset == off) {
1079 *pa = (mp->tlbpage << 7) | poff;
1080 return(1);
1081 }
1082 }
1083 return(0);
1084}
1085
1086STATIC
1087readdata()
1088{
1089 char *tmp, *mach_malloc();
1090 long size;
1091
1092 /* easy scalars */
1093 mach_read("equiv_end", ~0, (char *)&equiv_end, sizeof equiv_end);
1094 mach_read("vm_first_phys", ~0,
1095 (char *)&vm_first_phys, sizeof vm_first_phys);
1096 mach_read("vm_last_phys", ~0,
1097 (char *)&vm_last_phys, sizeof vm_last_phys);
1098 mach_read("firstmap", ~0, (char *)&firstmap, sizeof firstmap);
1099 mach_read("lastmap", ~0, (char *)&lastmap, sizeof lastmap);
1100
1101 /* virtual to physical hash table */
1102 vtopsize = HP800_HASHSIZE;
1103 size = vtopsize * sizeof(queue_head_t);
1104 tmp = mach_malloc("vtop table", size);
1105 mach_read("vtop_table", ~0, (char *)&Ovtop_table, sizeof Ovtop_table);
1106 mach_read("vtop table", (CORE_ADDR)Ovtop_table, tmp, size);
1107 vtop_table = (queue_head_t *) tmp;
1108
1109 /* inverted page table */
1110 physsize = atop(vm_last_phys - vm_first_phys);
1111 size = physsize * sizeof(struct phys_entry);
1112 tmp = mach_malloc("phys table", size);
1113 mach_read("phys_table", ~0, (char *)&Ophys_table, sizeof Ophys_table);
1114 mach_read("phys table", (CORE_ADDR)Ophys_table, tmp, size);
1115 phys_table = (struct phys_entry *) tmp;
1116
1117 /* mapping structures */
1118 Ofree_mapping = (queue_head_t *) ksym_lookup("free_mapping");
1119 mach_read("free mapping", (CORE_ADDR)Ofree_mapping,
1120 (char *) &free_mapping, sizeof free_mapping);
1121 Omap_table = firstmap;
1122 mapsize = lastmap - firstmap;
1123 size = mapsize * sizeof(struct mapping);
1124 tmp = mach_malloc("mapping table", size);
1125 mach_read("mapping table", (CORE_ADDR)Omap_table, tmp, size);
1126 map_table = (struct mapping *) tmp;
1127
1128 /* set limits */
1129 Ovlow = (unsigned) Ovtop_table;
1130 Ovhigh = (unsigned) &Ovtop_table[vtopsize];
1131 Oplow = (unsigned) Ophys_table;
1132 Ophigh = (unsigned) &Ophys_table[physsize];
1133 Omhead = (unsigned) Ofree_mapping;
1134 Omlow = (unsigned) firstmap;
1135 Omhigh = (unsigned) lastmap;
1136 mlow = (unsigned) map_table;
1137 mhigh = (unsigned) &map_table[mapsize];
1138 mhead = (unsigned) &free_mapping;
1139 vlow = (unsigned) vtop_table;
1140 vhigh = (unsigned) &vtop_table[vtopsize];
1141 plow = (unsigned) phys_table;
1142 phigh = (unsigned) &phys_table[physsize];
1143
1144#if 0
1145 fprintf(stderr, "Ovtop [%#x-%#x) Ophys [%#x-%#x) Omap %#x [%#x-%#x)\n",
1146 Ovlow, Ovhigh, Oplow, Ophigh, Omhead, Omlow, Omhigh);
1147 fprintf(stderr, "vtop [%#x-%#x) phys [%#x-%#x) map %#x [%#x-%#x)\n",
1148 vlow, vhigh, plow, phigh, mhead, mlow, mhigh);
1149#endif
1150 return(adjustdata());
1151}
1152
1153STATIC unsigned
1154ptrcvt(ptr)
1155 unsigned ptr;
1156{
1157 unsigned ret;
1158 char *str;
1159
1160 if (ptr == 0) {
1161 ret = ptr;
1162 str = "null";
1163 } else if (IS_OVTOPPTR(ptr)) {
1164 ret = vlow + (ptr - Ovlow);
1165 str = "vtop";
1166 } else if (IS_OPHYSPTR(ptr)) {
1167 ret = plow + (ptr - Oplow);
1168 str = "phys";
1169 } else if (IS_OMAPPTR(ptr)) {
1170 ret = mlow + (ptr - Omlow);
1171 str = "map";
1172 } else if (ptr == Omhead) {
1173 ret = mhead;
1174 str = "maphead";
1175 } else {
1176 error("bogus pointer %#x", ptr);
1177 str = "wild";
1178 ret = ptr;
1179 }
1180#if 0
1181 fprintf(stderr, "%x (%s) -> %x\n", ptr, str, ret);
1182#endif
1183 return(ret);
1184}
1185
1186STATIC int
1187adjustdata()
1188{
1189 register int i, lim;
1190 queue_head_t *nq;
1191 struct phys_entry *np;
1192 struct mapping *nm;
1193
1194 /* hash table */
1195 lim = vtopsize;
1196 for (nq = vtop_table; nq < &vtop_table[lim]; nq++) {
1197 nq->next = (queue_entry_t) ptrcvt((unsigned)nq->next);
1198 nq->prev = (queue_entry_t) ptrcvt((unsigned)nq->prev);
1199 }
1200
1201 /* IPT */
1202 lim = physsize;
1203 for (np = phys_table; np < &phys_table[lim]; np++) {
1204 np->phys_link.next = (queue_entry_t)
1205 ptrcvt((unsigned)np->phys_link.next);
1206 np->phys_link.prev = (queue_entry_t)
1207 ptrcvt((unsigned)np->phys_link.prev);
1208 np->writer = (struct mapping *) ptrcvt((unsigned)np->writer);
1209 }
1210
1211 /* mapping table */
1212 free_mapping.next = (queue_entry_t)ptrcvt((unsigned)free_mapping.next);
1213 free_mapping.prev = (queue_entry_t)ptrcvt((unsigned)free_mapping.prev);
1214 lim = mapsize;
1215 for (nm = map_table; nm < &map_table[lim]; nm++) {
1216 nm->hash_link.next = (queue_entry_t)
1217 ptrcvt((unsigned)nm->hash_link.next);
1218 nm->hash_link.prev = (queue_entry_t)
1219 ptrcvt((unsigned)nm->hash_link.prev);
1220 nm->phys_link.next = (queue_entry_t)
1221 ptrcvt((unsigned)nm->phys_link.next);
1222 nm->phys_link.prev = (queue_entry_t)
1223 ptrcvt((unsigned)nm->phys_link.prev);
1224 }
1225 return(1);
1226}
1227
1228/*
1229 * Consistency checks, make sure:
1230 *
1231 * 1. all mappings are accounted for
1232 * 2. no cycles
1233 * 3. no wild pointers
1234 * 4. consisent TLB state
1235 */
1236STATIC int
1237verifydata()
1238{
1239 register struct mapstate *ms;
1240 register int i;
1241 int errors = 0;
1242
1243 mapstate = (struct mapstate *)
1244 mach_malloc("map state", mapsize * sizeof(struct mapstate));
1245 for (ms = mapstate; ms < &mapstate[mapsize]; ms++) {
1246 ms->flags = 0;
1247 ms->hashix = ms->physix = -2;
1248 }
1249
1250 /*
1251 * Check the free list
1252 */
1253 checkhashchain(&free_mapping, M_ISFREE, -1);
1254 /*
1255 * Check every hash chain
1256 */
1257 for (i = 0; i < vtopsize; i++)
1258 checkhashchain(&vtop_table[i], M_ISHASH, i);
1259 /*
1260 * Check every phys chain
1261 */
1262 for (i = 0; i < physsize; i++)
1263 checkphyschain(&phys_table[i].phys_link, M_ISPHYS, i);
1264 /*
1265 * Cycle through mapstate looking for anomolies
1266 */
1267 ms = mapstate;
1268 for (i = 0; i < mapsize; i++) {
1269 switch (ms->flags) {
1270 case M_ISFREE:
1271 case M_ISHASH|M_ISPHYS:
1272 break;
1273 case 0:
1274 merror(ms, "not found");
1275 errors++;
1276 break;
1277 case M_ISHASH:
1278 merror(ms, "in vtop but not phys");
1279 errors++;
1280 break;
1281 case M_ISPHYS:
1282 merror(ms, "in phys but not vtop");
1283 errors++;
1284 break;
1285 default:
1286 merror(ms, "totally bogus");
1287 errors++;
1288 break;
1289 }
1290 ms++;
1291 }
1292 return(errors ? 0 : 1);
1293}
1294
1295STATIC void
1296checkhashchain(qhp, flag, ix)
1297 queue_entry_t qhp;
1298{
1299 register queue_entry_t qp, pqp;
1300 register struct mapping *mp;
1301 struct mapstate *ms;
1302
1303 qp = qhp->next;
1304 /*
1305 * First element is not a mapping structure,
1306 * chain must be empty.
1307 */
1308 if (!IS_MAPPTR(qp)) {
1309 if (qp != qhp || qp != qhp->prev)
1310 fatal("bad vtop_table header pointer");
1311 } else {
1312 pqp = qhp;
1313 do {
1314 mp = (struct mapping *) qp;
1315 qp = &mp->hash_link;
1316 if (qp->prev != pqp)
1317 fatal("bad hash_link prev pointer");
1318 ms = &mapstate[mp-map_table];
1319 ms->flags |= flag;
1320 ms->hashix = ix;
1321 pqp = (queue_entry_t) mp;
1322 qp = qp->next;
1323 } while (IS_MAPPTR(qp));
1324 if (qp != qhp)
1325 fatal("bad hash_link next pointer");
1326 }
1327}
1328
1329STATIC void
1330checkphyschain(qhp, flag, ix)
1331 queue_entry_t qhp;
1332{
1333 register queue_entry_t qp, pqp;
1334 register struct mapping *mp;
1335 struct mapstate *ms;
1336
1337 qp = qhp->next;
1338 /*
1339 * First element is not a mapping structure,
1340 * chain must be empty.
1341 */
1342 if (!IS_MAPPTR(qp)) {
1343 if (qp != qhp || qp != qhp->prev)
1344 fatal("bad phys_table header pointer");
1345 } else {
1346 pqp = qhp;
1347 do {
1348 mp = (struct mapping *) qp;
1349 qp = &mp->phys_link;
1350 if (qp->prev != pqp)
1351 fatal("bad phys_link prev pointer");
1352 ms = &mapstate[mp-map_table];
1353 ms->flags |= flag;
1354 ms->physix = ix;
1355 pqp = (queue_entry_t) mp;
1356 qp = qp->next;
1357 } while (IS_MAPPTR(qp));
1358 if (qp != qhp)
1359 fatal("bad phys_link next pointer");
1360 }
1361}
1362
1363STATIC void
1364merror(ms, str)
1365 struct mapstate *ms;
1366 char *str;
1367{
1368 terminal_ours();
1369 fflush(stdout);
1370 fprintf(stderr,
1371 "vtophys: %s: %c%c%c, hashix %d, physix %d, mapping %x\n",
1372 str,
1373 (ms->flags & M_ISFREE) ? 'F' : '-',
1374 (ms->flags & M_ISHASH) ? 'H' : '-',
1375 (ms->flags & M_ISPHYS) ? 'P' : '-',
1376 ms->hashix, ms->physix, &map_table[ms-mapstate]);
1377 return_to_top_level();
1378}
1379
1380STATIC int
1381mach_read(str, from, top, size)
1382 char *str;
1383 CORE_ADDR from;
1384 char *top;
1385 int size;
1386{
1387 CORE_ADDR paddr;
1388
1389 if (from == ~0)
1390 from = ksym_lookup(str);
1391 paddr = vtophys(0, from);
1392 if (paddr == ~0 || physrd(paddr, top, size) != 0)
1393 fatal("cannot read %s", str);
1394}
1395
1396STATIC char *
1397mach_malloc(str, size)
1398 char *str;
1399 int size;
1400{
1401 char *ptr = (char *) malloc(size);
1402
1403 if (ptr == 0)
1404 fatal("no memory for %s", str);
1405 return(ptr);
1406}
1407#endif
1408
1409#ifdef KERNELDEBUG
1410void
1411_initialize_hp9k8_dep()
1412{
1413 add_com ("process-address", class_obscure, set_paddr_command,
1414"The process identified by (ps-style) ADDR becomes the\n\
1415\"current\" process context for kernel debugging.");
1416 add_com_alias ("paddr", "process-address", class_obscure, 0);
1417 add_com ("virtual-to-physical", class_obscure, vtop_command,
1418"Translates the kernel virtual address ADDR into a physical address.");
1419 add_com_alias ("vtop", "virtual-to-physical", class_obscure, 0);
1420}
1421#endif
This page took 0.081781 seconds and 4 git commands to generate.