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.
5 Contributed by the Center for Software Science at the
6 University of Utah (pa-gdb-bugs@cs.utah.edu).
8 This file is part of GDB.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
29 /* For argument passing to the inferior */
33 #include <sys/types.h>
36 #include <sys/param.h>
39 #include <sys/ioctl.h>
41 #ifdef COFF_ENCAPSULATE
42 #include "a.out.encap.h"
47 #define N_SET_MAGIC(exec, val) ((exec).a_magic = (val))
50 /*#include <sys/user.h> After a.out.h */
53 #include <machine/psl.h>
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>
66 extern int kernel_debugging
;
67 extern CORE_ADDR startup_file_start
;
68 extern CORE_ADDR startup_file_end
;
70 #define KERNOFF ((unsigned)KERNBASE)
71 #define INKERNEL(x) ((x) >= KERNOFF && (x) < KERNOFF + ctob(slr))
73 static int ok_to_cache();
74 static void set_kernel_boundaries();
77 int vtophys_ready
= 0;
93 /* Last modification time of executable file.
94 Also used in source.c to compare against mtime of a source file. */
96 extern int exec_mtime
;
98 /* Virtual addresses of bounds of the two areas of memory in the core file. */
100 /* extern CORE_ADDR data_start; */
101 extern CORE_ADDR data_end
;
102 extern CORE_ADDR stack_start
;
103 extern CORE_ADDR stack_end
;
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. */
108 extern CORE_ADDR text_start
;
109 extern CORE_ADDR text_end
;
111 extern CORE_ADDR exec_data_start
;
112 extern CORE_ADDR exec_data_end
;
114 /* Address in executable file of start of text area data. */
116 extern int text_offset
;
118 /* Address in executable file of start of data area data. */
120 extern int exec_data_offset
;
122 /* Address in core file of start of data area data. */
124 extern int data_offset
;
126 /* Address in core file of start of stack area data. */
128 extern int stack_offset
;
130 struct header file_hdr
;
131 struct som_exec_auxhdr exec_hdr
;
135 * Kernel debugging routines.
138 static struct pcb pcb
;
139 static struct pde
*pdir
;
140 static struct hte
*htbl
;
141 static u_int npdir
, nhtbl
;
150 if ((i
= lookup_misc_func(name
)) < 0)
151 error("kernel symbol `%s' not found.", name
);
153 return (misc_function_vector
[i
].address
);
157 * (re-)set the variables that tell "inside_entry_file" where to end
161 set_kernel_boundaries()
163 switch (kerneltype
) {
165 startup_file_start
= ksym_lookup("$syscall");
166 startup_file_end
= ksym_lookup("trap");
169 startup_file_start
= ksym_lookup("syscallinit");
170 startup_file_end
= ksym_lookup("$syscallexit");
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).
181 ok_to_cache(addr
, len
)
183 static CORE_ADDR ioptr
;
186 ioptr
= ksym_lookup("ioptr");
188 if (addr
>= ioptr
&& addr
< SPA_HIGH
)
195 physrd(addr
, dat
, len
)
199 if (lseek(corechan
, addr
, L_SET
) == -1)
201 if (read(corechan
, dat
, len
) != len
)
208 * When looking at kernel data space through /dev/mem or with a core file, do
209 * virtual memory mapping.
217 u_int hindx
, vpageno
, ppageno
;
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
);
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.
230 hindx
= pdirhash(space
, addr
) & (nhtbl
-1);
231 pptr
= (struct pde
*) &htbl
[hindx
];
232 ppageno
= pptr
->pde_next
;
236 pptr
= &pdir
[ppageno
];
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.
242 if (pptr
->pde_space
== space
&&
243 pptr
->pde_page
== vpageno
) {
244 phys
= (CORE_ADDR
) ((u_int
)ptob(ppageno
) |
248 ppageno
= pptr
->pde_next
;
251 #ifdef MACHKERNELDEBUG
252 else if (kerneltype
== OS_MACH
) {
253 mach_vtophys(space
, addr
, &phys
);
257 printf("vtophys(%x.%x) -> %x\n", space
, addr
, phys
);
268 paddr
= vtophys(0, addr
);
270 if (physrd(paddr
, (char *)&addr
, sizeof(addr
)) == 0)
281 extern char registers
[];
282 static int reg2pcb
[] = {
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,
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,
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,
305 static struct rpb
*rpbaddr
= (struct rpb
*) 0;
306 static u_int rpbpcbaddr
= 0;
308 if (!remote_debugging
) {
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.
314 if (!devmem
&& rpbpcbaddr
== 0) {
315 CORE_ADDR raddr
= ksym_lookup("rpb");
319 rpbaddr
= (struct rpb
*) malloc(sizeof *rpbaddr
);
320 if (!physrd(raddr
, (char *)rpbaddr
, sizeof *rpbaddr
)) {
326 error("cannot read rpb, using pcb for registers\n");
328 free((char *)rpbaddr
);
332 if (physrd (addr
, (char *)&pcb
, sizeof pcb
))
333 error ("cannot read pcb at %x.\n", addr
);
335 if (remote_read_inferior_memory(addr
, (char *)&pcb
, sizeof pcb
))
336 error ("cannot read pcb at %x.\n", addr
);
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
);
344 printf("pcb %lx psw %lx ksp %lx\n",
345 addr
, ((int *)&pcb
)[31], ((int *)&pcb
)[32]);
349 * get the register values out of the sys pcb and
350 * store them where `read_register' will find them.
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
]]);
357 * If the RPB is valid for this thread/proc use the register values
360 if (addr
== rpbpcbaddr
) {
362 for (i
= 0; i
< NUM_REGS
; ++i
)
363 if (reg2pcb
[i
+off
] != -1)
364 supply_register(i
, &((int *)rpbaddr
)[reg2pcb
[i
+off
]]);
369 setup_kernel_debugging()
374 fstat(corechan
, &stb
);
376 if ((stb
.st_mode
& S_IFMT
) == S_IFCHR
&& stb
.st_rdev
== makedev(2, 0))
380 if (lookup_misc_func("Sysmap") < 0)
381 kerneltype
= OS_MACH
;
385 if (kerneltype
== OS_BSD
) {
389 * Hash table and PDIR are equivalently mapped
391 nhtbl
= kvread(ksym_lookup("nhtbl"));
393 len
= nhtbl
* sizeof(*htbl
);
394 htbl
= (struct hte
*) malloc(len
);
396 addr
= kvread(ksym_lookup("htbl"));
397 if (physrd(addr
, (char *)htbl
, len
))
403 npdir
= kvread(ksym_lookup("npdir"));
405 len
= npdir
* sizeof(*pdir
);
406 pdir
= (struct pde
*) malloc(len
);
408 addr
= kvread(ksym_lookup("pdir"));
409 if (physrd(addr
, (char *)pdir
, len
))
416 error("cannot read PDIR/HTBL");
422 * pcb where "panic" saved registers in first thing in
423 * current u-area. The current u-area is pointed to by
426 addr
= kvread(ksym_lookup("uptr"));
428 error("cannot read current u-area address");
431 read_pcb(vtophys(0, addr
)); /* XXX space */
433 /* find stack frame */
438 panicstr
= kvread(ksym_lookup("panicstr"));
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
)))
447 printf("panic: %s\n", buf
);
450 #ifdef MACHKERNELDEBUG
455 * Set up address translation
457 if (mach_vtophys_init() == 0) {
458 error("cannot initialize vtophys for Mach");
464 * Locate active thread and read PCB
466 * - assumes uni-processor
467 * - assumes position of pcb to avoid mach includes
469 thread
= (int *)kvread(ksym_lookup("active_threads"));
470 addr
= kvread(&thread
[9]); /* XXX: pcb addr */
471 read_pcb(vtophys(0, addr
));
482 error_no_arg("kernel virtual address");
483 if (!kernel_debugging
)
484 error("not debugging kernel");
487 off
= (u_int
) parse_and_eval_address(arg
);
488 pa
= vtophys(sp
, off
);
489 printf("%lx.%lx -> ", sp
, off
);
491 printf("<invalid>\n");
496 set_paddr_command(arg
)
502 if (kerneltype
== OS_BSD
)
503 error_no_arg("ps-style address for new process");
505 error_no_arg("thread structure virtual address");
507 if (!kernel_debugging
)
508 error("not debugging kernel");
510 addr
= (u_int
) parse_and_eval_address(arg
);
511 if (kerneltype
== OS_BSD
)
514 addr
= kvread(&(((int *)addr
)[9])); /* XXX: pcb addr */
515 addr
= vtophys(0, addr
); /* XXX space */
519 flush_cached_frames();
520 set_current_frame(create_new_frame(read_register(FP_REGNUM
), read_pc()));
521 select_frame(get_current_frame(), 0);
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.
529 kernel_core_file_hook(addr
, buf
, len
)
538 paddr
= vtophys(0, addr
); /* XXX space */
543 /* we can't read across a page boundary */
544 i
= min(len
, NBPG
- (addr
& PGOFSET
));
545 if (physrd(paddr
, buf
, i
)) {
562 /* Routines to extract various sized constants out of hppa
565 /* This assumes that no garbage lies outside of the lower bits of
569 sign_extend (val
, bits
)
572 return (int)(val
>> bits
- 1 ? (-1 << bits
) | val
: val
);
575 /* For many immediate values the sign bit is the low bit! */
578 low_sign_extend (val
, bits
)
581 return (int)((val
& 0x1 ? (-1 << (bits
- 1)) : 0) | val
>> 1);
583 /* extract the immediate field from a ld{bhw}s instruction */
588 get_field (val
, from
, to
)
589 unsigned val
, from
, to
;
591 val
= val
>> 31 - to
;
592 return val
& ((1 << 32 - from
) - 1);
596 set_field (val
, from
, to
, new_val
)
597 unsigned *val
, from
, to
;
599 unsigned mask
= ~((1 << (to
- from
+ 1)) << (31 - from
));
600 return *val
= *val
& mask
| (new_val
<< (31 - from
));
603 /* extract a 3-bit space register number from a be, ble, mtsp or mfsp */
608 return GET_FIELD (word
, 18, 18) << 2 | GET_FIELD (word
, 16, 17);
611 extract_5_load (word
)
614 return low_sign_extend (word
>> 16 & MASK_5
, 5);
617 /* extract the immediate field from a st{bhw}s instruction */
620 extract_5_store (word
)
623 return low_sign_extend (word
& MASK_5
, 5);
626 /* extract an 11 bit immediate field */
632 return low_sign_extend (word
& MASK_11
, 11);
635 /* extract a 14 bit immediate field */
641 return low_sign_extend (word
& MASK_14
, 14);
644 /* deposit a 14 bit constant in a word */
647 deposit_14 (opnd
, word
)
651 unsigned sign
= (opnd
< 0 ? 1 : 0);
653 return word
| ((unsigned)opnd
<< 1 & MASK_14
) | sign
;
656 /* extract a 21 bit constant */
666 val
= GET_FIELD (word
, 20, 20);
668 val
|= GET_FIELD (word
, 9, 19);
670 val
|= GET_FIELD (word
, 5, 6);
672 val
|= GET_FIELD (word
, 0, 4);
674 val
|= GET_FIELD (word
, 7, 8);
675 return sign_extend (val
, 21) << 11;
678 /* deposit a 21 bit constant in a word. Although 21 bit constants are
679 usually the top 21 bits of a 32 bit constant, we assume that only
680 the low 21 bits of opnd are relevant */
683 deposit_21 (opnd
, word
)
688 val
|= GET_FIELD (opnd
, 11 + 14, 11 + 18);
690 val
|= GET_FIELD (opnd
, 11 + 12, 11 + 13);
692 val
|= GET_FIELD (opnd
, 11 + 19, 11 + 20);
694 val
|= GET_FIELD (opnd
, 11 + 1, 11 + 11);
696 val
|= GET_FIELD (opnd
, 11 + 0, 11 + 0);
700 /* extract a 12 bit constant from branch instructions */
706 return sign_extend (GET_FIELD (word
, 19, 28) |
707 GET_FIELD (word
, 29, 29) << 10 |
708 (word
& 0x1) << 11, 12) << 2;
711 /* extract a 17 bit constant from branch instructions, returning the
712 19 bit signed value. */
718 return sign_extend (GET_FIELD (word
, 19, 28) |
719 GET_FIELD (word
, 29, 29) << 10 |
720 GET_FIELD (word
, 11, 15) << 11 |
721 (word
& 0x1) << 16, 17) << 2;
726 frame_saved_pc (frame
)
729 if (get_current_frame () == frame
)
731 struct frame_saved_regs saved_regs
;
732 CORE_ADDR pc
= get_frame_pc (frame
);
734 get_frame_saved_regs (frame
, &saved_regs
);
735 if (pc
>= millicode_start
&& pc
< millicode_end
)
736 return read_register (31);
737 else if (saved_regs
.regs
[RP_REGNUM
])
738 return read_memory_integer (saved_regs
.regs
[RP_REGNUM
], 4);
740 return read_register (RP_REGNUM
);
742 return read_memory_integer (frame
->frame
- 20, 4) & ~0x3;
746 /* To see if a frame chain is valid, see if the caller looks like it
747 was compiled with gcc. */
749 int frame_chain_valid (chain
, thisframe
)
753 if (chain
&& (chain
> 0x60000000
754 /* || remote_debugging -this is no longer used */
760 CORE_ADDR pc
= get_pc_function_start (FRAME_SAVED_PC (thisframe
));
762 if (!inside_entry_file (pc
))
764 /* look for stw rp, -20(0,sp); copy 4,1; copy sp, 4 */
765 if (read_memory_integer (pc
, 4) == 0x6BC23FD9)
768 if (read_memory_integer (pc
, 4) == 0x8040241 &&
769 read_memory_integer (pc
+ 4, 4) == 0x81E0244)
778 /* Some helper functions. gcc_p returns 1 if the function beginning at
779 pc appears to have been compiled with gcc. hpux_cc_p returns 1 if
780 fn was compiled with hpux cc. gcc functions look like :
782 stw rp,-0x14(sp) ; optional
785 stwm r1,framesize(sp)
787 hpux cc functions look like:
789 stw rp,-0x14(sp) ; optional.
796 if (read_memory_integer (pc
, 4) == 0x6BC23FD9)
799 if (read_memory_integer (pc
, 4) == 0x8040241 &&
800 read_memory_integer (pc
+ 4, 4) == 0x81E0244)
806 find_dummy_frame_regs (frame
, frame_saved_regs
)
807 struct frame_info
*frame
;
808 struct frame_saved_regs
*frame_saved_regs
;
810 CORE_ADDR fp
= frame
->frame
;
813 frame_saved_regs
->regs
[RP_REGNUM
] = fp
- 20 & ~0x3;
814 frame_saved_regs
->regs
[FP_REGNUM
] = fp
;
815 frame_saved_regs
->regs
[1] = fp
+ 8;
816 frame_saved_regs
->regs
[3] = fp
+ 12;
817 for (fp
+= 16, i
= 3; i
< 30; fp
+= 4, i
++)
818 frame_saved_regs
->regs
[i
] = fp
;
819 frame_saved_regs
->regs
[31] = fp
;
821 for (i
= FP0_REGNUM
; i
< NUM_REGS
; i
++, fp
+= 8)
822 frame_saved_regs
->regs
[i
] = fp
;
823 /* depend on last increment of fp */
824 frame_saved_regs
->regs
[IPSW_REGNUM
] = fp
- 4;
825 frame_saved_regs
->regs
[SAR_REGNUM
] = fp
;
827 frame_saved_regs
->regs
[PCOQ_TAIL_REGNUM
] = fp
;
828 frame_saved_regs
->regs
[PCSQ_TAIL_REGNUM
] = fp
;
832 hp_push_arguments (nargs
, args
, sp
, struct_return
, struct_addr
)
837 CORE_ADDR struct_addr
;
839 /* array of arguments' offsets */
840 int *offset
= (int *)alloca(nargs
);
844 for (i
= 0; i
< nargs
; i
++)
846 cum
+= TYPE_LENGTH (VALUE_TYPE (args
[i
]));
847 /* value must go at proper alignment. Assume alignment is a
849 alignment
= hp_alignof (VALUE_TYPE (args
[i
]));
851 cum
= (cum
+ alignment
) & -alignment
;
854 for (i
== 0; i
< nargs
; i
++)
856 write_memory (sp
+ offset
[i
], VALUE_CONTENTS (args
[i
]), sizeof(int));
858 sp
+= min ((cum
+ 7) & -8, 48);
860 write_register (28, struct_addr
);
864 /* return the alignment of a type in bytes. Structures have the maximum
865 alignment required by their fields. */
871 int max_align
, align
, i
;
872 switch (TYPE_CODE (arg
))
877 return TYPE_LENGTH (arg
);
878 case TYPE_CODE_ARRAY
:
879 return hp_alignof (TYPE_FIELD_TYPE (arg
, 0));
880 case TYPE_CODE_STRUCT
:
881 case TYPE_CODE_UNION
:
883 for (i
= 0; i
< TYPE_NFIELDS (arg
); i
++)
885 /* Bit fields have no real alignment. */
886 if (!TYPE_FIELD_BITPOS (arg
, i
))
888 align
= hp_alignof (TYPE_FIELD_TYPE (arg
, i
));
889 max_align
= max (max_align
, align
);
898 /* Print the register regnum, or all registers if regnum is -1 */
900 pa_do_registers_info (regnum
, fpregs
)
904 char raw_regs
[REGISTER_BYTES
];
907 for (i
= 0; i
< NUM_REGS
; i
++)
908 read_relative_register_raw_bytes (i
, raw_regs
+ REGISTER_BYTE (i
));
910 pa_print_registers (raw_regs
, regnum
);
911 else if (regnum
< FP0_REGNUM
)
913 printf ("%s %x\n", reg_names
[regnum
], *(long *)(raw_regs
+
914 REGISTER_BYTE (regnum
)));
917 pa_print_fp_reg (regnum
);
920 pa_print_registers (raw_regs
, regnum
)
926 for (i
= 0; i
< 18; i
++)
927 printf ("%8.8s: %8x %8.8s: %8x %8.8s: %8x %8.8s: %8x\n",
929 *(int *)(raw_regs
+ REGISTER_BYTE (i
)),
931 *(int *)(raw_regs
+ REGISTER_BYTE (i
+ 18)),
933 *(int *)(raw_regs
+ REGISTER_BYTE (i
+ 36)),
935 *(int *)(raw_regs
+ REGISTER_BYTE (i
+ 54)));
936 for (i
= 72; i
< NUM_REGS
; i
++)
943 unsigned char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
944 unsigned char virtual_buffer
[MAX_REGISTER_VIRTUAL_SIZE
];
947 /* Get the data in raw format, then convert also to virtual format. */
948 read_relative_register_raw_bytes (i
, raw_buffer
);
949 REGISTER_CONVERT_TO_VIRTUAL (i
, raw_buffer
, virtual_buffer
);
951 fputs_filtered (reg_names
[i
], stdout
);
952 print_spaces_filtered (15 - strlen (reg_names
[i
]), stdout
);
954 val_print (REGISTER_VIRTUAL_TYPE (i
), virtual_buffer
, 0, stdout
, 0,
955 1, 0, Val_pretty_default
);
956 printf_filtered ("\n");
961 * Virtual to physical translation routines for Utah's Mach 3.0
963 #ifdef MACHKERNELDEBUG
967 #if 0 /* too many includes to resolve, too much crap */
968 #include <kern/queue.h>
970 #include <mach/vm_prot.h>
974 struct queue_entry
*next
; /* next element */
975 struct queue_entry
*prev
; /* previous element */
978 typedef struct queue_entry
*queue_t
;
979 typedef struct queue_entry queue_head_t
;
980 typedef struct queue_entry queue_chain_t
;
981 typedef struct queue_entry
*queue_entry_t
;
984 #define HP800_HASHSIZE 1024
985 #define HP800_HASHSIZE_LOG2 10
987 #define pmap_hash(space, offset) \
988 (((unsigned) (space) << 5 ^ \
989 ((unsigned) (offset) >> 19 | (unsigned) (space) << 13) ^ \
990 (unsigned) (offset) >> 11) & (HP800_HASHSIZE-1))
993 queue_head_t hash_link
; /* hash table links */
994 queue_head_t phys_link
; /* for mappings of a given PA */
995 space_t space
; /* virtual space */
996 unsigned offset
; /* virtual page number */
997 unsigned tlbpage
; /* physical page (for TLB load) */
998 unsigned tlbprot
; /* prot/access rights (for TLB load) */
999 struct pmap
*pmap
; /* pmap mapping belongs to */
1003 queue_head_t phys_link
; /* head of mappings of a given PA */
1004 struct mapping
*writer
; /* mapping with R/W access */
1005 unsigned tlbprot
; /* TLB format protection */
1010 #define atop(a) ((unsigned)(a) >> 11)
1011 #define ptoa(p) ((unsigned)(p) << 11)
1012 #define trunc_page(a) ((unsigned)(a) & ~2047)
1014 STATIC
long equiv_end
;
1015 STATIC queue_head_t
*Ovtop_table
, *vtop_table
, *Ofree_mapping
, free_mapping
;
1016 STATIC
struct phys_entry
*Ophys_table
, *phys_table
;
1017 STATIC
long vm_last_phys
, vm_first_phys
;
1018 STATIC
struct mapping
*firstmap
, *lastmap
, *Omap_table
, *map_table
;
1019 STATIC
unsigned Omlow
, Omhigh
, Omhead
, Ovlow
, Ovhigh
, Oplow
, Ophigh
;
1020 STATIC
unsigned mlow
, mhigh
, mhead
, vlow
, vhigh
, plow
, phigh
;
1021 STATIC
int vtopsize
, physsize
, mapsize
;
1024 #define IS_OVTOPPTR(p) ((unsigned)(p) >= Ovlow && (unsigned)(p) < Ovhigh)
1025 #define IS_OMAPPTR(p) ((unsigned)(p) >= Omlow && (unsigned)(p) < Omhigh)
1026 #define IS_OPHYSPTR(p) ((unsigned)(p) >= Oplow && (unsigned)(p) < Ophigh)
1027 #define IS_VTOPPTR(p) ((unsigned)(p) >= vlow && (unsigned)(p) < vhigh)
1028 #define IS_MAPPTR(p) ((unsigned)(p) >= mlow && (unsigned)(p) < mhigh)
1029 #define IS_PHYSPTR(p) ((unsigned)(p) >= plow && (unsigned)(p) < phigh)
1055 "translate: may not be able to translate all addresses\n");
1059 mach_vtophys(space
, off
, pa
)
1060 unsigned space
, off
, *pa
;
1063 register queue_t qp
;
1064 register struct mapping
*mp
;
1068 * Kernel IO or equivilently mapped, one to one.
1070 if (space
== 0 && (long)off
< equiv_end
) {
1075 * Else look it up in specified space
1077 poff
= off
- trunc_page(off
);
1078 off
= trunc_page(off
);
1079 qp
= &vtop_table
[pmap_hash(space
, off
)];
1080 for (mp
= (struct mapping
*)qp
->next
;
1081 qp
!= (queue_entry_t
)mp
;
1082 mp
= (struct mapping
*)mp
->hash_link
.next
) {
1083 if (mp
->space
== space
&& mp
->offset
== off
) {
1084 *pa
= (mp
->tlbpage
<< 7) | poff
;
1094 char *tmp
, *mach_malloc();
1098 mach_read("equiv_end", ~0, (char *)&equiv_end
, sizeof equiv_end
);
1099 mach_read("vm_first_phys", ~0,
1100 (char *)&vm_first_phys
, sizeof vm_first_phys
);
1101 mach_read("vm_last_phys", ~0,
1102 (char *)&vm_last_phys
, sizeof vm_last_phys
);
1103 mach_read("firstmap", ~0, (char *)&firstmap
, sizeof firstmap
);
1104 mach_read("lastmap", ~0, (char *)&lastmap
, sizeof lastmap
);
1106 /* virtual to physical hash table */
1107 vtopsize
= HP800_HASHSIZE
;
1108 size
= vtopsize
* sizeof(queue_head_t
);
1109 tmp
= mach_malloc("vtop table", size
);
1110 mach_read("vtop_table", ~0, (char *)&Ovtop_table
, sizeof Ovtop_table
);
1111 mach_read("vtop table", (CORE_ADDR
)Ovtop_table
, tmp
, size
);
1112 vtop_table
= (queue_head_t
*) tmp
;
1114 /* inverted page table */
1115 physsize
= atop(vm_last_phys
- vm_first_phys
);
1116 size
= physsize
* sizeof(struct phys_entry
);
1117 tmp
= mach_malloc("phys table", size
);
1118 mach_read("phys_table", ~0, (char *)&Ophys_table
, sizeof Ophys_table
);
1119 mach_read("phys table", (CORE_ADDR
)Ophys_table
, tmp
, size
);
1120 phys_table
= (struct phys_entry
*) tmp
;
1122 /* mapping structures */
1123 Ofree_mapping
= (queue_head_t
*) ksym_lookup("free_mapping");
1124 mach_read("free mapping", (CORE_ADDR
)Ofree_mapping
,
1125 (char *) &free_mapping
, sizeof free_mapping
);
1126 Omap_table
= firstmap
;
1127 mapsize
= lastmap
- firstmap
;
1128 size
= mapsize
* sizeof(struct mapping
);
1129 tmp
= mach_malloc("mapping table", size
);
1130 mach_read("mapping table", (CORE_ADDR
)Omap_table
, tmp
, size
);
1131 map_table
= (struct mapping
*) tmp
;
1134 Ovlow
= (unsigned) Ovtop_table
;
1135 Ovhigh
= (unsigned) &Ovtop_table
[vtopsize
];
1136 Oplow
= (unsigned) Ophys_table
;
1137 Ophigh
= (unsigned) &Ophys_table
[physsize
];
1138 Omhead
= (unsigned) Ofree_mapping
;
1139 Omlow
= (unsigned) firstmap
;
1140 Omhigh
= (unsigned) lastmap
;
1141 mlow
= (unsigned) map_table
;
1142 mhigh
= (unsigned) &map_table
[mapsize
];
1143 mhead
= (unsigned) &free_mapping
;
1144 vlow
= (unsigned) vtop_table
;
1145 vhigh
= (unsigned) &vtop_table
[vtopsize
];
1146 plow
= (unsigned) phys_table
;
1147 phigh
= (unsigned) &phys_table
[physsize
];
1150 fprintf(stderr
, "Ovtop [%#x-%#x) Ophys [%#x-%#x) Omap %#x [%#x-%#x)\n",
1151 Ovlow
, Ovhigh
, Oplow
, Ophigh
, Omhead
, Omlow
, Omhigh
);
1152 fprintf(stderr
, "vtop [%#x-%#x) phys [%#x-%#x) map %#x [%#x-%#x)\n",
1153 vlow
, vhigh
, plow
, phigh
, mhead
, mlow
, mhigh
);
1155 return(adjustdata());
1168 } else if (IS_OVTOPPTR(ptr
)) {
1169 ret
= vlow
+ (ptr
- Ovlow
);
1171 } else if (IS_OPHYSPTR(ptr
)) {
1172 ret
= plow
+ (ptr
- Oplow
);
1174 } else if (IS_OMAPPTR(ptr
)) {
1175 ret
= mlow
+ (ptr
- Omlow
);
1177 } else if (ptr
== Omhead
) {
1181 error("bogus pointer %#x", ptr
);
1186 fprintf(stderr
, "%x (%s) -> %x\n", ptr
, str
, ret
);
1194 register int i
, lim
;
1196 struct phys_entry
*np
;
1201 for (nq
= vtop_table
; nq
< &vtop_table
[lim
]; nq
++) {
1202 nq
->next
= (queue_entry_t
) ptrcvt((unsigned)nq
->next
);
1203 nq
->prev
= (queue_entry_t
) ptrcvt((unsigned)nq
->prev
);
1208 for (np
= phys_table
; np
< &phys_table
[lim
]; np
++) {
1209 np
->phys_link
.next
= (queue_entry_t
)
1210 ptrcvt((unsigned)np
->phys_link
.next
);
1211 np
->phys_link
.prev
= (queue_entry_t
)
1212 ptrcvt((unsigned)np
->phys_link
.prev
);
1213 np
->writer
= (struct mapping
*) ptrcvt((unsigned)np
->writer
);
1217 free_mapping
.next
= (queue_entry_t
)ptrcvt((unsigned)free_mapping
.next
);
1218 free_mapping
.prev
= (queue_entry_t
)ptrcvt((unsigned)free_mapping
.prev
);
1220 for (nm
= map_table
; nm
< &map_table
[lim
]; nm
++) {
1221 nm
->hash_link
.next
= (queue_entry_t
)
1222 ptrcvt((unsigned)nm
->hash_link
.next
);
1223 nm
->hash_link
.prev
= (queue_entry_t
)
1224 ptrcvt((unsigned)nm
->hash_link
.prev
);
1225 nm
->phys_link
.next
= (queue_entry_t
)
1226 ptrcvt((unsigned)nm
->phys_link
.next
);
1227 nm
->phys_link
.prev
= (queue_entry_t
)
1228 ptrcvt((unsigned)nm
->phys_link
.prev
);
1234 * Consistency checks, make sure:
1236 * 1. all mappings are accounted for
1238 * 3. no wild pointers
1239 * 4. consisent TLB state
1244 register struct mapstate
*ms
;
1248 mapstate
= (struct mapstate
*)
1249 mach_malloc("map state", mapsize
* sizeof(struct mapstate
));
1250 for (ms
= mapstate
; ms
< &mapstate
[mapsize
]; ms
++) {
1252 ms
->hashix
= ms
->physix
= -2;
1256 * Check the free list
1258 checkhashchain(&free_mapping
, M_ISFREE
, -1);
1260 * Check every hash chain
1262 for (i
= 0; i
< vtopsize
; i
++)
1263 checkhashchain(&vtop_table
[i
], M_ISHASH
, i
);
1265 * Check every phys chain
1267 for (i
= 0; i
< physsize
; i
++)
1268 checkphyschain(&phys_table
[i
].phys_link
, M_ISPHYS
, i
);
1270 * Cycle through mapstate looking for anomolies
1273 for (i
= 0; i
< mapsize
; i
++) {
1274 switch (ms
->flags
) {
1276 case M_ISHASH
|M_ISPHYS
:
1279 merror(ms
, "not found");
1283 merror(ms
, "in vtop but not phys");
1287 merror(ms
, "in phys but not vtop");
1291 merror(ms
, "totally bogus");
1297 return(errors
? 0 : 1);
1301 checkhashchain(qhp
, flag
, ix
)
1304 register queue_entry_t qp
, pqp
;
1305 register struct mapping
*mp
;
1306 struct mapstate
*ms
;
1310 * First element is not a mapping structure,
1311 * chain must be empty.
1313 if (!IS_MAPPTR(qp
)) {
1314 if (qp
!= qhp
|| qp
!= qhp
->prev
)
1315 fatal("bad vtop_table header pointer");
1319 mp
= (struct mapping
*) qp
;
1320 qp
= &mp
->hash_link
;
1321 if (qp
->prev
!= pqp
)
1322 fatal("bad hash_link prev pointer");
1323 ms
= &mapstate
[mp
-map_table
];
1326 pqp
= (queue_entry_t
) mp
;
1328 } while (IS_MAPPTR(qp
));
1330 fatal("bad hash_link next pointer");
1335 checkphyschain(qhp
, flag
, ix
)
1338 register queue_entry_t qp
, pqp
;
1339 register struct mapping
*mp
;
1340 struct mapstate
*ms
;
1344 * First element is not a mapping structure,
1345 * chain must be empty.
1347 if (!IS_MAPPTR(qp
)) {
1348 if (qp
!= qhp
|| qp
!= qhp
->prev
)
1349 fatal("bad phys_table header pointer");
1353 mp
= (struct mapping
*) qp
;
1354 qp
= &mp
->phys_link
;
1355 if (qp
->prev
!= pqp
)
1356 fatal("bad phys_link prev pointer");
1357 ms
= &mapstate
[mp
-map_table
];
1360 pqp
= (queue_entry_t
) mp
;
1362 } while (IS_MAPPTR(qp
));
1364 fatal("bad phys_link next pointer");
1370 struct mapstate
*ms
;
1376 "vtophys: %s: %c%c%c, hashix %d, physix %d, mapping %x\n",
1378 (ms
->flags
& M_ISFREE
) ? 'F' : '-',
1379 (ms
->flags
& M_ISHASH
) ? 'H' : '-',
1380 (ms
->flags
& M_ISPHYS
) ? 'P' : '-',
1381 ms
->hashix
, ms
->physix
, &map_table
[ms
-mapstate
]);
1382 return_to_top_level();
1386 mach_read(str
, from
, top
, size
)
1395 from
= ksym_lookup(str
);
1396 paddr
= vtophys(0, from
);
1397 if (paddr
== ~0 || physrd(paddr
, top
, size
) != 0)
1398 fatal("cannot read %s", str
);
1402 mach_malloc(str
, size
)
1406 char *ptr
= (char *) malloc(size
);
1409 fatal("no memory for %s", str
);
1416 _initialize_hp9k8_dep()
1418 add_com ("process-address", class_obscure
, set_paddr_command
,
1419 "The process identified by (ps-style) ADDR becomes the\n\
1420 \"current\" process context for kernel debugging.");
1421 add_com_alias ("paddr", "process-address", class_obscure
, 0);
1422 add_com ("virtual-to-physical", class_obscure
, vtop_command
,
1423 "Translates the kernel virtual address ADDR into a physical address.");
1424 add_com_alias ("vtop", "virtual-to-physical", class_obscure
, 0);