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 (C) 1986, 1987, 1989, 1990, 1991 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 GDB 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 1, or (at your option)
15 GDB 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 GDB; see the file COPYING. If not, write to
22 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
30 /* For argument passing to the inferior */
34 #include <sys/types.h>
37 #include <sys/param.h>
40 #include <sys/ioctl.h>
41 /* #include <fcntl.h> Can we live without this? */
43 #ifdef COFF_ENCAPSULATE
44 #include "a.out.encap.h"
49 #define N_SET_MAGIC(exec, val) ((exec).a_magic = (val))
52 /*#include <sys/user.h> After a.out.h */
55 #include <sys/ptrace.h>
56 #include <machine/psl.h>
59 #include <sys/vmmac.h>
60 #include <machine/machparam.h>
61 #include <machine/vmparam.h>
62 #include <machine/pde.h>
63 #include <machine/cpu.h>
64 #include <machine/iomod.h>
65 #include <machine/pcb.h>
66 #include <machine/rpb.h>
69 extern int kernel_debugging
;
70 extern CORE_ADDR startup_file_start
;
71 extern CORE_ADDR startup_file_end
;
73 #define KERNOFF ((unsigned)KERNBASE)
74 #define INKERNEL(x) ((x) >= KERNOFF && (x) < KERNOFF + ctob(slr))
76 static int ok_to_cache();
77 static void set_kernel_boundaries();
80 int vtophys_ready
= 0;
96 /* Last modification time of executable file.
97 Also used in source.c to compare against mtime of a source file. */
99 extern int exec_mtime
;
101 /* Virtual addresses of bounds of the two areas of memory in the core file. */
103 /* extern CORE_ADDR data_start; */
104 extern CORE_ADDR data_end
;
105 extern CORE_ADDR stack_start
;
106 extern CORE_ADDR stack_end
;
108 /* Virtual addresses of bounds of two areas of memory in the exec file.
109 Note that the data area in the exec file is used only when there is no core file. */
111 extern CORE_ADDR text_start
;
112 extern CORE_ADDR text_end
;
114 extern CORE_ADDR exec_data_start
;
115 extern CORE_ADDR exec_data_end
;
117 /* Address in executable file of start of text area data. */
119 extern int text_offset
;
121 /* Address in executable file of start of data area data. */
123 extern int exec_data_offset
;
125 /* Address in core file of start of data area data. */
127 extern int data_offset
;
129 /* Address in core file of start of stack area data. */
131 extern int stack_offset
;
133 struct header file_hdr
;
134 struct som_exec_auxhdr exec_hdr
;
138 * Kernel debugging routines.
141 static struct pcb pcb
;
142 static struct pde
*pdir
;
143 static struct hte
*htbl
;
144 static u_int npdir
, nhtbl
;
153 if ((i
= lookup_misc_func(name
)) < 0)
154 error("kernel symbol `%s' not found.", name
);
156 return (misc_function_vector
[i
].address
);
160 * (re-)set the variables that tell "inside_entry_file" where to end
164 set_kernel_boundaries()
166 switch (kerneltype
) {
168 startup_file_start
= ksym_lookup("$syscall");
169 startup_file_end
= ksym_lookup("trap");
172 startup_file_start
= ksym_lookup("syscallinit");
173 startup_file_end
= ksym_lookup("$syscallexit");
179 * return true if 'len' bytes starting at 'addr' can be read out as
180 * longwords and/or locally cached (this is mostly for memory mapped
181 * i/o register access when debugging remote kernels).
184 ok_to_cache(addr
, len
)
186 static CORE_ADDR ioptr
;
189 ioptr
= ksym_lookup("ioptr");
191 if (addr
>= ioptr
&& addr
< SPA_HIGH
)
198 physrd(addr
, dat
, len
)
202 if (lseek(corechan
, addr
, L_SET
) == -1)
204 if (read(corechan
, dat
, len
) != len
)
211 * When looking at kernel data space through /dev/mem or with a core file, do
212 * virtual memory mapping.
220 u_int hindx
, vpageno
, ppageno
;
223 if (!vtophys_ready
) {
224 phys
= addr
; /* XXX for kvread */
225 } else if (kerneltype
== OS_BSD
) {
226 /* make offset into a virtual page no */
227 vpageno
= btop(addr
);
229 * Determine index into hash table, initialize pptr to this
230 * entry (since first word of pte & hte are same), and set
231 * physical page number for first entry in chain.
233 hindx
= pdirhash(space
, addr
) & (nhtbl
-1);
234 pptr
= (struct pde
*) &htbl
[hindx
];
235 ppageno
= pptr
->pde_next
;
239 pptr
= &pdir
[ppageno
];
241 * If space id & virtual page number match, return
242 * "next PDIR entry of previous PDIR entry" as the
243 * physical page or'd with offset into page.
245 if (pptr
->pde_space
== space
&&
246 pptr
->pde_page
== vpageno
) {
247 phys
= (CORE_ADDR
) ((u_int
)ptob(ppageno
) |
251 ppageno
= pptr
->pde_next
;
254 #ifdef MACHKERNELDEBUG
255 else if (kerneltype
== OS_MACH
) {
256 (void) mach_vtophys(space
, addr
, &phys
);
260 printf("vtophys(%x.%x) -> %x\n", space
, addr
, phys
);
271 paddr
= vtophys(0, addr
);
273 if (physrd(paddr
, (char *)&addr
, sizeof(addr
)) == 0)
284 extern char registers
[];
285 static int reg2pcb
[] = {
287 -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
288 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
289 45, 52, 51, 75, 74, 49, 53, 54, 55, 56, -1, 70, 66, 67, 68, 69,
290 71, 72, 73, 34, 42, 43, 44, 46, 47, 58, 59, 60, -1, -1, -1, -1,
291 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
294 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
295 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
296 43, 64, 67, 68, 67, 47, 51, 52, 53, 54, -1, 35, 31, 32, 33, 34,
297 36, 37, 38, 39, 40, 41, 42, 44, 45, 56, 57, 58,102,103,104, -1,
298 70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 82, 84, 86, 88, 90, 92,
301 -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
302 14, 15, 16, -1, -1, -1, -1, -1, -1, -1, -1, 17, -1, -1, 18, -1,
303 25, -1, -1, -1, -1, 30, -1, -1, -1, -1, -1, 20, -1, -1, -1, 19,
304 21, 22, 23, 24, 26, 27, -1, 28, 29, -1, -1, -1, -1, -1, -1, -1,
305 34, 35, 36, 37, 38, 39, 40, 41, -1, -1, -1, -1, -1, -1, -1, -1,
308 static struct rpb
*rpbaddr
= (struct rpb
*) 0;
309 static u_int rpbpcbaddr
= 0;
311 if (!remote_debugging
) {
313 * If we are debugging a post-mortem and this is the first
314 * call of read_pcb, read the RPB. Also assoicate the
315 * thread/proc running at the time with the RPB.
317 if (!devmem
&& rpbpcbaddr
== 0) {
318 CORE_ADDR raddr
= ksym_lookup("rpb");
322 rpbaddr
= (struct rpb
*) malloc(sizeof *rpbaddr
);
323 if (!physrd(raddr
, (char *)rpbaddr
, sizeof *rpbaddr
)) {
329 error("cannot read rpb, using pcb for registers\n");
331 free((char *)rpbaddr
);
335 if (physrd (addr
, (char *)&pcb
, sizeof pcb
))
336 error ("cannot read pcb at %x.\n", addr
);
338 if (remote_read_inferior_memory(addr
, (char *)&pcb
, sizeof pcb
))
339 error ("cannot read pcb at %x.\n", addr
);
342 if (kerneltype
== OS_BSD
) {
343 printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n",
344 pcb
.pcb_p0br
, pcb
.pcb_p0lr
, pcb
.pcb_p1br
, pcb
.pcb_p1lr
);
347 printf("pcb %lx psw %lx ksp %lx\n",
348 addr
, ((int *)&pcb
)[31], ((int *)&pcb
)[32]);
352 * get the register values out of the sys pcb and
353 * store them where `read_register' will find them.
355 bzero(registers
, REGISTER_BYTES
);
356 for (i
= 0; i
< NUM_REGS
; ++i
)
357 if (reg2pcb
[i
+off
] != -1)
358 supply_register(i
, &((int *)&pcb
)[reg2pcb
[i
+off
]]);
360 * If the RPB is valid for this thread/proc use the register values
363 if (addr
== rpbpcbaddr
) {
365 for (i
= 0; i
< NUM_REGS
; ++i
)
366 if (reg2pcb
[i
+off
] != -1)
367 supply_register(i
, &((int *)rpbaddr
)[reg2pcb
[i
+off
]]);
372 setup_kernel_debugging()
377 fstat(corechan
, &stb
);
379 if ((stb
.st_mode
& S_IFMT
) == S_IFCHR
&& stb
.st_rdev
== makedev(2, 0))
383 if (lookup_misc_func("Sysmap") < 0)
384 kerneltype
= OS_MACH
;
388 if (kerneltype
== OS_BSD
) {
392 * Hash table and PDIR are equivalently mapped
394 nhtbl
= kvread(ksym_lookup("nhtbl"));
396 len
= nhtbl
* sizeof(*htbl
);
397 htbl
= (struct hte
*) malloc(len
);
399 addr
= kvread(ksym_lookup("htbl"));
400 if (physrd(addr
, (char *)htbl
, len
))
406 npdir
= kvread(ksym_lookup("npdir"));
408 len
= npdir
* sizeof(*pdir
);
409 pdir
= (struct pde
*) malloc(len
);
411 addr
= kvread(ksym_lookup("pdir"));
412 if (physrd(addr
, (char *)pdir
, len
))
419 error("cannot read PDIR/HTBL");
425 * pcb where "panic" saved registers in first thing in
426 * current u-area. The current u-area is pointed to by
429 addr
= kvread(ksym_lookup("uptr"));
431 error("cannot read current u-area address");
434 read_pcb(vtophys(0, addr
)); /* XXX space */
436 /* find stack frame */
441 panicstr
= kvread(ksym_lookup("panicstr"));
444 (void) kernel_core_file_hook(panicstr
, buf
, sizeof(buf
));
445 for (cp
= buf
; cp
< &buf
[sizeof(buf
)] && *cp
; cp
++)
446 if (!isascii(*cp
) || (!isprint(*cp
) && !isspace(*cp
)))
450 printf("panic: %s\n", buf
);
453 #ifdef MACHKERNELDEBUG
458 * Set up address translation
460 if (mach_vtophys_init() == 0) {
461 error("cannot initialize vtophys for Mach");
467 * Locate active thread and read PCB
469 * - assumes uni-processor
470 * - assumes position of pcb to avoid mach includes
472 thread
= (int *)kvread(ksym_lookup("active_threads"));
473 addr
= kvread(&thread
[9]); /* XXX: pcb addr */
474 read_pcb(vtophys(0, addr
));
485 error_no_arg("kernel virtual address");
486 if (!kernel_debugging
)
487 error("not debugging kernel");
490 off
= (u_int
) parse_and_eval_address(arg
);
491 pa
= vtophys(sp
, off
);
492 printf("%lx.%lx -> ", sp
, off
);
494 printf("<invalid>\n");
499 set_paddr_command(arg
)
505 if (kerneltype
== OS_BSD
)
506 error_no_arg("ps-style address for new process");
508 error_no_arg("thread structure virtual address");
510 if (!kernel_debugging
)
511 error("not debugging kernel");
513 addr
= (u_int
) parse_and_eval_address(arg
);
514 if (kerneltype
== OS_BSD
)
517 addr
= kvread(&(((int *)addr
)[9])); /* XXX: pcb addr */
518 addr
= vtophys(0, addr
); /* XXX space */
522 flush_cached_frames();
523 set_current_frame(create_new_frame(read_register(FP_REGNUM
), read_pc()));
524 select_frame(get_current_frame(), 0);
528 * read len bytes from kernel virtual address 'addr' into local
529 * buffer 'buf'. Return 0 if read ok, 1 otherwise. On read
530 * errors, portion of buffer not read is zeroed.
532 kernel_core_file_hook(addr
, buf
, len
)
541 paddr
= vtophys(0, addr
); /* XXX space */
546 /* we can't read across a page boundary */
547 i
= min(len
, NBPG
- (addr
& PGOFSET
));
548 if (physrd(paddr
, buf
, i
)) {
564 /* Routines to extract various sized constants out of hppa
567 /* This assumes that no garbage lies outside of the lower bits of
571 sign_extend (val
, bits
)
574 return (int)(val
>> bits
- 1 ? (-1 << bits
) | val
: val
);
577 /* For many immediate values the sign bit is the low bit! */
580 low_sign_extend (val
, bits
)
583 return (int)((val
& 0x1 ? (-1 << (bits
- 1)) : 0) | val
>> 1);
585 /* extract the immediate field from a ld{bhw}s instruction */
590 get_field (val
, from
, to
)
591 unsigned val
, from
, to
;
593 val
= val
>> 31 - to
;
594 return val
& ((1 << 32 - from
) - 1);
598 set_field (val
, from
, to
, new_val
)
599 unsigned *val
, from
, to
;
601 unsigned mask
= ~((1 << (to
- from
+ 1)) << (31 - from
));
602 return *val
= *val
& mask
| (new_val
<< (31 - from
));
605 /* extract a 3-bit space register number from a be, ble, mtsp or mfsp */
610 return GET_FIELD (word
, 18, 18) << 2 | GET_FIELD (word
, 16, 17);
613 extract_5_load (word
)
616 return low_sign_extend (word
>> 16 & MASK_5
, 5);
619 /* extract the immediate field from a st{bhw}s instruction */
622 extract_5_store (word
)
625 return low_sign_extend (word
& MASK_5
, 5);
628 /* extract an 11 bit immediate field */
634 return low_sign_extend (word
& MASK_11
, 11);
637 /* extract a 14 bit immediate field */
643 return low_sign_extend (word
& MASK_14
, 14);
646 /* deposit a 14 bit constant in a word */
649 deposit_14 (opnd
, word
)
653 unsigned sign
= (opnd
< 0 ? 1 : 0);
655 return word
| ((unsigned)opnd
<< 1 & MASK_14
) | sign
;
658 /* extract a 21 bit constant */
668 val
= GET_FIELD (word
, 20, 20);
670 val
|= GET_FIELD (word
, 9, 19);
672 val
|= GET_FIELD (word
, 5, 6);
674 val
|= GET_FIELD (word
, 0, 4);
676 val
|= GET_FIELD (word
, 7, 8);
677 return sign_extend (val
, 21) << 11;
680 /* deposit a 21 bit constant in a word. Although 21 bit constants are
681 usually the top 21 bits of a 32 bit constant, we assume that only
682 the low 21 bits of opnd are relevant */
685 deposit_21 (opnd
, word
)
690 val
|= GET_FIELD (opnd
, 11 + 14, 11 + 18);
692 val
|= GET_FIELD (opnd
, 11 + 12, 11 + 13);
694 val
|= GET_FIELD (opnd
, 11 + 19, 11 + 20);
696 val
|= GET_FIELD (opnd
, 11 + 1, 11 + 11);
698 val
|= GET_FIELD (opnd
, 11 + 0, 11 + 0);
702 /* extract a 12 bit constant from branch instructions */
708 return sign_extend (GET_FIELD (word
, 19, 28) |
709 GET_FIELD (word
, 29, 29) << 10 |
710 (word
& 0x1) << 11, 12) << 2;
713 /* extract a 17 bit constant from branch instructions, returning the
714 19 bit signed value. */
720 return sign_extend (GET_FIELD (word
, 19, 28) |
721 GET_FIELD (word
, 29, 29) << 10 |
722 GET_FIELD (word
, 11, 15) << 11 |
723 (word
& 0x1) << 16, 17) << 2;
728 frame_saved_pc (frame
)
731 if (get_current_frame () == frame
)
733 struct frame_saved_regs saved_regs
;
735 get_frame_saved_regs (frame
, &saved_regs
);
736 if (saved_regs
.regs
[RP_REGNUM
])
737 return read_memory_integer (saved_regs
.regs
[RP_REGNUM
], 4);
739 return read_register (RP_REGNUM
);
741 return read_memory_integer (frame
->frame
- 20, 4) & ~0x3;
744 /* To see if a frame chain is valid, see if the caller looks like it
745 was compiled with gcc. */
747 int frame_chain_valid (chain
, thisframe
)
751 if (chain
&& (chain
> 0x60000000
752 /* || remote_debugging -this is no longer used */
758 CORE_ADDR pc
= get_pc_function_start (FRAME_SAVED_PC (thisframe
));
760 if (!inside_entry_file (pc
))
762 /* look for stw rp, -20(0,sp); copy 4,1; copy sp, 4 */
763 if (read_memory_integer (pc
, 4) == 0x6BC23FD9)
766 if (read_memory_integer (pc
, 4) == 0x8040241 &&
767 read_memory_integer (pc
+ 4, 4) == 0x81E0244)
776 /* Some helper functions. gcc_p returns 1 if the function beginning at
777 pc appears to have been compiled with gcc. hpux_cc_p returns 1 if
778 fn was compiled with hpux cc. gcc functions look like :
780 stw rp,-0x14(sp) ; optional
783 stwm r1,framesize(sp)
785 hpux cc functions look like:
787 stw rp,-0x14(sp) ; optional.
794 if (read_memory_integer (pc
, 4) == 0x6BC23FD9)
797 if (read_memory_integer (pc
, 4) == 0x8040241 &&
798 read_memory_integer (pc
+ 4, 4) == 0x81E0244)
804 find_dummy_frame_regs (frame
, frame_saved_regs
)
805 struct frame_info
*frame
;
806 struct frame_saved_regs
*frame_saved_regs
;
808 CORE_ADDR fp
= frame
->frame
;
811 frame_saved_regs
->regs
[RP_REGNUM
] = fp
- 20 & ~0x3;
812 frame_saved_regs
->regs
[FP_REGNUM
] = fp
;
813 frame_saved_regs
->regs
[1] = fp
+ 8;
814 frame_saved_regs
->regs
[3] = fp
+ 12;
815 for (fp
+= 16, i
= 3; i
< 30; fp
+= 4, i
++)
816 frame_saved_regs
->regs
[i
] = fp
;
817 frame_saved_regs
->regs
[31] = fp
;
819 for (i
= FP0_REGNUM
; i
< NUM_REGS
; i
++, fp
+= 8)
820 frame_saved_regs
->regs
[i
] = fp
;
821 /* depend on last increment of fp */
822 frame_saved_regs
->regs
[IPSW_REGNUM
] = fp
- 4;
823 frame_saved_regs
->regs
[SAR_REGNUM
] = fp
;
825 frame_saved_regs
->regs
[PCOQ_TAIL_REGNUM
] = fp
;
826 frame_saved_regs
->regs
[PCSQ_TAIL_REGNUM
] = fp
;
830 hp_push_arguments (nargs
, args
, sp
, struct_return
, struct_addr
)
835 CORE_ADDR struct_addr
;
837 /* array of arguments' offsets */
838 int *offset
= (int *)alloca(nargs
);
842 for (i
= 0; i
< nargs
; i
++)
844 cum
+= TYPE_LENGTH (VALUE_TYPE (args
[i
]));
845 /* value must go at proper alignment. Assume alignment is a
847 alignment
= hp_alignof (VALUE_TYPE (args
[i
]));
849 cum
= (cum
+ alignment
) & -alignment
;
852 for (i
== 0; i
< nargs
; i
++)
854 write_memory (sp
+ offset
[i
], VALUE_CONTENTS (args
[i
]), sizeof(int));
856 sp
+= min ((cum
+ 7) & -8, 48);
858 write_register (28, struct_addr
);
862 /* return the alignment of a type in bytes. Structures have the maximum
863 alignment required by their fields. */
869 int max_align
, align
, i
;
870 switch (TYPE_CODE (arg
))
875 return TYPE_LENGTH (arg
);
876 case TYPE_CODE_ARRAY
:
877 return hp_alignof (TYPE_FIELD_TYPE (arg
, 0));
878 case TYPE_CODE_STRUCT
:
879 case TYPE_CODE_UNION
:
881 for (i
= 0; i
< TYPE_NFIELDS (arg
); i
++)
883 /* Bit fields have no real alignment. */
884 if (!TYPE_FIELD_BITPOS (arg
, i
))
886 align
= hp_alignof (TYPE_FIELD_TYPE (arg
, i
));
887 max_align
= max (max_align
, align
);
896 /* Print the register regnum, or all registers if regnum is -1 */
898 pa_do_registers_info (regnum
, fpregs
)
902 char raw_regs
[REGISTER_BYTES
];
905 for (i
= 0; i
< NUM_REGS
; i
++)
906 read_relative_register_raw_bytes (i
, raw_regs
+ REGISTER_BYTE (i
));
908 pa_print_registers (raw_regs
, regnum
);
909 else if (regnum
< FP0_REGNUM
)
911 printf ("%s %x\n", reg_names
[regnum
], *(long *)(raw_regs
+
912 REGISTER_BYTE (regnum
)));
915 pa_print_fp_reg (regnum
);
918 pa_print_registers (raw_regs
, regnum
)
924 for (i
= 0; i
< 18; i
++)
925 printf ("%8.8s: %8x %8.8s: %8x %8.8s: %8x %8.8s: %8x\n",
927 *(int *)(raw_regs
+ REGISTER_BYTE (i
)),
929 *(int *)(raw_regs
+ REGISTER_BYTE (i
+ 18)),
931 *(int *)(raw_regs
+ REGISTER_BYTE (i
+ 36)),
933 *(int *)(raw_regs
+ REGISTER_BYTE (i
+ 54)));
934 for (i
= 72; i
< NUM_REGS
; i
++)
941 unsigned char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
942 unsigned char virtual_buffer
[MAX_REGISTER_VIRTUAL_SIZE
];
945 /* Get the data in raw format, then convert also to virtual format. */
946 read_relative_register_raw_bytes (i
, raw_buffer
);
947 REGISTER_CONVERT_TO_VIRTUAL (i
, raw_buffer
, virtual_buffer
);
949 fputs_filtered (reg_names
[i
], stdout
);
950 print_spaces_filtered (15 - strlen (reg_names
[i
]), stdout
);
952 val_print (REGISTER_VIRTUAL_TYPE (i
), virtual_buffer
, 0, stdout
, 0,
953 1, 0, Val_pretty_default
);
954 printf_filtered ("\n");
959 * Virtual to physical translation routines for Utah's Mach 3.0
961 #ifdef MACHKERNELDEBUG
965 #if 0 /* too many includes to resolve, too much crap */
966 #include <kern/queue.h>
968 #include <mach/vm_prot.h>
972 struct queue_entry
*next
; /* next element */
973 struct queue_entry
*prev
; /* previous element */
976 typedef struct queue_entry
*queue_t
;
977 typedef struct queue_entry queue_head_t
;
978 typedef struct queue_entry queue_chain_t
;
979 typedef struct queue_entry
*queue_entry_t
;
982 #define HP800_HASHSIZE 1024
983 #define HP800_HASHSIZE_LOG2 10
985 #define pmap_hash(space, offset) \
986 (((unsigned) (space) << 5 ^ \
987 ((unsigned) (offset) >> 19 | (unsigned) (space) << 13) ^ \
988 (unsigned) (offset) >> 11) & (HP800_HASHSIZE-1))
991 queue_head_t hash_link
; /* hash table links */
992 queue_head_t phys_link
; /* for mappings of a given PA */
993 space_t space
; /* virtual space */
994 unsigned offset
; /* virtual page number */
995 unsigned tlbpage
; /* physical page (for TLB load) */
996 unsigned tlbprot
; /* prot/access rights (for TLB load) */
997 struct pmap
*pmap
; /* pmap mapping belongs to */
1001 queue_head_t phys_link
; /* head of mappings of a given PA */
1002 struct mapping
*writer
; /* mapping with R/W access */
1003 unsigned tlbprot
; /* TLB format protection */
1008 #define atop(a) ((unsigned)(a) >> 11)
1009 #define ptoa(p) ((unsigned)(p) << 11)
1010 #define trunc_page(a) ((unsigned)(a) & ~2047)
1012 STATIC
long equiv_end
;
1013 STATIC queue_head_t
*Ovtop_table
, *vtop_table
, *Ofree_mapping
, free_mapping
;
1014 STATIC
struct phys_entry
*Ophys_table
, *phys_table
;
1015 STATIC
long vm_last_phys
, vm_first_phys
;
1016 STATIC
struct mapping
*firstmap
, *lastmap
, *Omap_table
, *map_table
;
1017 STATIC
unsigned Omlow
, Omhigh
, Omhead
, Ovlow
, Ovhigh
, Oplow
, Ophigh
;
1018 STATIC
unsigned mlow
, mhigh
, mhead
, vlow
, vhigh
, plow
, phigh
;
1019 STATIC
int vtopsize
, physsize
, mapsize
;
1022 #define IS_OVTOPPTR(p) ((unsigned)(p) >= Ovlow && (unsigned)(p) < Ovhigh)
1023 #define IS_OMAPPTR(p) ((unsigned)(p) >= Omlow && (unsigned)(p) < Omhigh)
1024 #define IS_OPHYSPTR(p) ((unsigned)(p) >= Oplow && (unsigned)(p) < Ophigh)
1025 #define IS_VTOPPTR(p) ((unsigned)(p) >= vlow && (unsigned)(p) < vhigh)
1026 #define IS_MAPPTR(p) ((unsigned)(p) >= mlow && (unsigned)(p) < mhigh)
1027 #define IS_PHYSPTR(p) ((unsigned)(p) >= plow && (unsigned)(p) < phigh)
1053 "translate: may not be able to translate all addresses\n");
1057 mach_vtophys(space
, off
, pa
)
1058 unsigned space
, off
, *pa
;
1061 register queue_t qp
;
1062 register struct mapping
*mp
;
1066 * Kernel IO or equivilently mapped, one to one.
1068 if (space
== 0 && (long)off
< equiv_end
) {
1073 * Else look it up in specified space
1075 poff
= off
- trunc_page(off
);
1076 off
= trunc_page(off
);
1077 qp
= &vtop_table
[pmap_hash(space
, off
)];
1078 for (mp
= (struct mapping
*)qp
->next
;
1079 qp
!= (queue_entry_t
)mp
;
1080 mp
= (struct mapping
*)mp
->hash_link
.next
) {
1081 if (mp
->space
== space
&& mp
->offset
== off
) {
1082 *pa
= (mp
->tlbpage
<< 7) | poff
;
1092 char *tmp
, *mach_malloc();
1096 mach_read("equiv_end", ~0, (char *)&equiv_end
, sizeof equiv_end
);
1097 mach_read("vm_first_phys", ~0,
1098 (char *)&vm_first_phys
, sizeof vm_first_phys
);
1099 mach_read("vm_last_phys", ~0,
1100 (char *)&vm_last_phys
, sizeof vm_last_phys
);
1101 mach_read("firstmap", ~0, (char *)&firstmap
, sizeof firstmap
);
1102 mach_read("lastmap", ~0, (char *)&lastmap
, sizeof lastmap
);
1104 /* virtual to physical hash table */
1105 vtopsize
= HP800_HASHSIZE
;
1106 size
= vtopsize
* sizeof(queue_head_t
);
1107 tmp
= mach_malloc("vtop table", size
);
1108 mach_read("vtop_table", ~0, (char *)&Ovtop_table
, sizeof Ovtop_table
);
1109 mach_read("vtop table", (CORE_ADDR
)Ovtop_table
, tmp
, size
);
1110 vtop_table
= (queue_head_t
*) tmp
;
1112 /* inverted page table */
1113 physsize
= atop(vm_last_phys
- vm_first_phys
);
1114 size
= physsize
* sizeof(struct phys_entry
);
1115 tmp
= mach_malloc("phys table", size
);
1116 mach_read("phys_table", ~0, (char *)&Ophys_table
, sizeof Ophys_table
);
1117 mach_read("phys table", (CORE_ADDR
)Ophys_table
, tmp
, size
);
1118 phys_table
= (struct phys_entry
*) tmp
;
1120 /* mapping structures */
1121 Ofree_mapping
= (queue_head_t
*) ksym_lookup("free_mapping");
1122 mach_read("free mapping", (CORE_ADDR
)Ofree_mapping
,
1123 (char *) &free_mapping
, sizeof free_mapping
);
1124 Omap_table
= firstmap
;
1125 mapsize
= lastmap
- firstmap
;
1126 size
= mapsize
* sizeof(struct mapping
);
1127 tmp
= mach_malloc("mapping table", size
);
1128 mach_read("mapping table", (CORE_ADDR
)Omap_table
, tmp
, size
);
1129 map_table
= (struct mapping
*) tmp
;
1132 Ovlow
= (unsigned) Ovtop_table
;
1133 Ovhigh
= (unsigned) &Ovtop_table
[vtopsize
];
1134 Oplow
= (unsigned) Ophys_table
;
1135 Ophigh
= (unsigned) &Ophys_table
[physsize
];
1136 Omhead
= (unsigned) Ofree_mapping
;
1137 Omlow
= (unsigned) firstmap
;
1138 Omhigh
= (unsigned) lastmap
;
1139 mlow
= (unsigned) map_table
;
1140 mhigh
= (unsigned) &map_table
[mapsize
];
1141 mhead
= (unsigned) &free_mapping
;
1142 vlow
= (unsigned) vtop_table
;
1143 vhigh
= (unsigned) &vtop_table
[vtopsize
];
1144 plow
= (unsigned) phys_table
;
1145 phigh
= (unsigned) &phys_table
[physsize
];
1148 fprintf(stderr
, "Ovtop [%#x-%#x) Ophys [%#x-%#x) Omap %#x [%#x-%#x)\n",
1149 Ovlow
, Ovhigh
, Oplow
, Ophigh
, Omhead
, Omlow
, Omhigh
);
1150 fprintf(stderr
, "vtop [%#x-%#x) phys [%#x-%#x) map %#x [%#x-%#x)\n",
1151 vlow
, vhigh
, plow
, phigh
, mhead
, mlow
, mhigh
);
1153 return(adjustdata());
1166 } else if (IS_OVTOPPTR(ptr
)) {
1167 ret
= vlow
+ (ptr
- Ovlow
);
1169 } else if (IS_OPHYSPTR(ptr
)) {
1170 ret
= plow
+ (ptr
- Oplow
);
1172 } else if (IS_OMAPPTR(ptr
)) {
1173 ret
= mlow
+ (ptr
- Omlow
);
1175 } else if (ptr
== Omhead
) {
1179 error("bogus pointer %#x", ptr
);
1184 fprintf(stderr
, "%x (%s) -> %x\n", ptr
, str
, ret
);
1192 register int i
, lim
;
1194 struct phys_entry
*np
;
1199 for (nq
= vtop_table
; nq
< &vtop_table
[lim
]; nq
++) {
1200 nq
->next
= (queue_entry_t
) ptrcvt((unsigned)nq
->next
);
1201 nq
->prev
= (queue_entry_t
) ptrcvt((unsigned)nq
->prev
);
1206 for (np
= phys_table
; np
< &phys_table
[lim
]; np
++) {
1207 np
->phys_link
.next
= (queue_entry_t
)
1208 ptrcvt((unsigned)np
->phys_link
.next
);
1209 np
->phys_link
.prev
= (queue_entry_t
)
1210 ptrcvt((unsigned)np
->phys_link
.prev
);
1211 np
->writer
= (struct mapping
*) ptrcvt((unsigned)np
->writer
);
1215 free_mapping
.next
= (queue_entry_t
)ptrcvt((unsigned)free_mapping
.next
);
1216 free_mapping
.prev
= (queue_entry_t
)ptrcvt((unsigned)free_mapping
.prev
);
1218 for (nm
= map_table
; nm
< &map_table
[lim
]; nm
++) {
1219 nm
->hash_link
.next
= (queue_entry_t
)
1220 ptrcvt((unsigned)nm
->hash_link
.next
);
1221 nm
->hash_link
.prev
= (queue_entry_t
)
1222 ptrcvt((unsigned)nm
->hash_link
.prev
);
1223 nm
->phys_link
.next
= (queue_entry_t
)
1224 ptrcvt((unsigned)nm
->phys_link
.next
);
1225 nm
->phys_link
.prev
= (queue_entry_t
)
1226 ptrcvt((unsigned)nm
->phys_link
.prev
);
1232 * Consistency checks, make sure:
1234 * 1. all mappings are accounted for
1236 * 3. no wild pointers
1237 * 4. consisent TLB state
1242 register struct mapstate
*ms
;
1246 mapstate
= (struct mapstate
*)
1247 mach_malloc("map state", mapsize
* sizeof(struct mapstate
));
1248 for (ms
= mapstate
; ms
< &mapstate
[mapsize
]; ms
++) {
1250 ms
->hashix
= ms
->physix
= -2;
1254 * Check the free list
1256 checkhashchain(&free_mapping
, M_ISFREE
, -1);
1258 * Check every hash chain
1260 for (i
= 0; i
< vtopsize
; i
++)
1261 checkhashchain(&vtop_table
[i
], M_ISHASH
, i
);
1263 * Check every phys chain
1265 for (i
= 0; i
< physsize
; i
++)
1266 checkphyschain(&phys_table
[i
].phys_link
, M_ISPHYS
, i
);
1268 * Cycle through mapstate looking for anomolies
1271 for (i
= 0; i
< mapsize
; i
++) {
1272 switch (ms
->flags
) {
1274 case M_ISHASH
|M_ISPHYS
:
1277 merror(ms
, "not found");
1281 merror(ms
, "in vtop but not phys");
1285 merror(ms
, "in phys but not vtop");
1289 merror(ms
, "totally bogus");
1295 return(errors
? 0 : 1);
1299 checkhashchain(qhp
, flag
, ix
)
1302 register queue_entry_t qp
, pqp
;
1303 register struct mapping
*mp
;
1304 struct mapstate
*ms
;
1308 * First element is not a mapping structure,
1309 * chain must be empty.
1311 if (!IS_MAPPTR(qp
)) {
1312 if (qp
!= qhp
|| qp
!= qhp
->prev
)
1313 fatal("bad vtop_table header pointer");
1317 mp
= (struct mapping
*) qp
;
1318 qp
= &mp
->hash_link
;
1319 if (qp
->prev
!= pqp
)
1320 fatal("bad hash_link prev pointer");
1321 ms
= &mapstate
[mp
-map_table
];
1324 pqp
= (queue_entry_t
) mp
;
1326 } while (IS_MAPPTR(qp
));
1328 fatal("bad hash_link next pointer");
1333 checkphyschain(qhp
, flag
, ix
)
1336 register queue_entry_t qp
, pqp
;
1337 register struct mapping
*mp
;
1338 struct mapstate
*ms
;
1342 * First element is not a mapping structure,
1343 * chain must be empty.
1345 if (!IS_MAPPTR(qp
)) {
1346 if (qp
!= qhp
|| qp
!= qhp
->prev
)
1347 fatal("bad phys_table header pointer");
1351 mp
= (struct mapping
*) qp
;
1352 qp
= &mp
->phys_link
;
1353 if (qp
->prev
!= pqp
)
1354 fatal("bad phys_link prev pointer");
1355 ms
= &mapstate
[mp
-map_table
];
1358 pqp
= (queue_entry_t
) mp
;
1360 } while (IS_MAPPTR(qp
));
1362 fatal("bad phys_link next pointer");
1368 struct mapstate
*ms
;
1374 "vtophys: %s: %c%c%c, hashix %d, physix %d, mapping %x\n",
1376 (ms
->flags
& M_ISFREE
) ? 'F' : '-',
1377 (ms
->flags
& M_ISHASH
) ? 'H' : '-',
1378 (ms
->flags
& M_ISPHYS
) ? 'P' : '-',
1379 ms
->hashix
, ms
->physix
, &map_table
[ms
-mapstate
]);
1380 return_to_top_level();
1384 mach_read(str
, from
, top
, size
)
1393 from
= ksym_lookup(str
);
1394 paddr
= vtophys(0, from
);
1395 if (paddr
== ~0 || physrd(paddr
, top
, size
) != 0)
1396 fatal("cannot read %s", str
);
1400 mach_malloc(str
, size
)
1404 char *ptr
= (char *) malloc(size
);
1407 fatal("no memory for %s", str
);
1414 _initialize_hp9k8_dep()
1416 add_com ("process-address", class_obscure
, set_paddr_command
,
1417 "The process identified by (ps-style) ADDR becomes the\n\
1418 \"current\" process context for kernel debugging.");
1419 add_com_alias ("paddr", "process-address", class_obscure
, 0);
1420 add_com ("virtual-to-physical", class_obscure
, vtop_command
,
1421 "Translates the kernel virtual address ADDR into a physical address.");
1422 add_com_alias ("vtop", "virtual-to-physical", class_obscure
, 0);