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
)) {
565 /* Routines to extract various sized constants out of hppa
568 /* This assumes that no garbage lies outside of the lower bits of
572 sign_extend (val
, bits
)
575 return (int)(val
>> bits
- 1 ? (-1 << bits
) | val
: val
);
578 /* For many immediate values the sign bit is the low bit! */
581 low_sign_extend (val
, bits
)
584 return (int)((val
& 0x1 ? (-1 << (bits
- 1)) : 0) | val
>> 1);
586 /* extract the immediate field from a ld{bhw}s instruction */
591 get_field (val
, from
, to
)
592 unsigned val
, from
, to
;
594 val
= val
>> 31 - to
;
595 return val
& ((1 << 32 - from
) - 1);
599 set_field (val
, from
, to
, new_val
)
600 unsigned *val
, from
, to
;
602 unsigned mask
= ~((1 << (to
- from
+ 1)) << (31 - from
));
603 return *val
= *val
& mask
| (new_val
<< (31 - from
));
606 /* extract a 3-bit space register number from a be, ble, mtsp or mfsp */
611 return GET_FIELD (word
, 18, 18) << 2 | GET_FIELD (word
, 16, 17);
614 extract_5_load (word
)
617 return low_sign_extend (word
>> 16 & MASK_5
, 5);
620 /* extract the immediate field from a st{bhw}s instruction */
623 extract_5_store (word
)
626 return low_sign_extend (word
& MASK_5
, 5);
629 /* extract an 11 bit immediate field */
635 return low_sign_extend (word
& MASK_11
, 11);
638 /* extract a 14 bit immediate field */
644 return low_sign_extend (word
& MASK_14
, 14);
647 /* deposit a 14 bit constant in a word */
650 deposit_14 (opnd
, word
)
654 unsigned sign
= (opnd
< 0 ? 1 : 0);
656 return word
| ((unsigned)opnd
<< 1 & MASK_14
) | sign
;
659 /* extract a 21 bit constant */
669 val
= GET_FIELD (word
, 20, 20);
671 val
|= GET_FIELD (word
, 9, 19);
673 val
|= GET_FIELD (word
, 5, 6);
675 val
|= GET_FIELD (word
, 0, 4);
677 val
|= GET_FIELD (word
, 7, 8);
678 return sign_extend (val
, 21) << 11;
681 /* deposit a 21 bit constant in a word. Although 21 bit constants are
682 usually the top 21 bits of a 32 bit constant, we assume that only
683 the low 21 bits of opnd are relevant */
686 deposit_21 (opnd
, word
)
691 val
|= GET_FIELD (opnd
, 11 + 14, 11 + 18);
693 val
|= GET_FIELD (opnd
, 11 + 12, 11 + 13);
695 val
|= GET_FIELD (opnd
, 11 + 19, 11 + 20);
697 val
|= GET_FIELD (opnd
, 11 + 1, 11 + 11);
699 val
|= GET_FIELD (opnd
, 11 + 0, 11 + 0);
703 /* extract a 12 bit constant from branch instructions */
709 return sign_extend (GET_FIELD (word
, 19, 28) |
710 GET_FIELD (word
, 29, 29) << 10 |
711 (word
& 0x1) << 11, 12) << 2;
714 /* extract a 17 bit constant from branch instructions, returning the
715 19 bit signed value. */
721 return sign_extend (GET_FIELD (word
, 19, 28) |
722 GET_FIELD (word
, 29, 29) << 10 |
723 GET_FIELD (word
, 11, 15) << 11 |
724 (word
& 0x1) << 16, 17) << 2;
729 frame_saved_pc (frame
)
732 if (get_current_frame () == frame
)
734 struct frame_saved_regs saved_regs
;
735 CORE_ADDR pc
= get_frame_pc (frame
);
737 get_frame_saved_regs (frame
, &saved_regs
);
738 if (pc
>= millicode_start
&& pc
< millicode_end
)
739 return read_register (31);
740 else if (saved_regs
.regs
[RP_REGNUM
])
741 return read_memory_integer (saved_regs
.regs
[RP_REGNUM
], 4);
743 return read_register (RP_REGNUM
);
745 return read_memory_integer (frame
->frame
- 20, 4) & ~0x3;
749 /* To see if a frame chain is valid, see if the caller looks like it
750 was compiled with gcc. */
752 int frame_chain_valid (chain
, thisframe
)
756 if (chain
&& (chain
> 0x60000000
757 /* || remote_debugging -this is no longer used */
763 CORE_ADDR pc
= get_pc_function_start (FRAME_SAVED_PC (thisframe
));
765 if (!inside_entry_file (pc
))
767 /* look for stw rp, -20(0,sp); copy 4,1; copy sp, 4 */
768 if (read_memory_integer (pc
, 4) == 0x6BC23FD9)
771 if (read_memory_integer (pc
, 4) == 0x8040241 &&
772 read_memory_integer (pc
+ 4, 4) == 0x81E0244)
781 /* Some helper functions. gcc_p returns 1 if the function beginning at
782 pc appears to have been compiled with gcc. hpux_cc_p returns 1 if
783 fn was compiled with hpux cc. gcc functions look like :
785 stw rp,-0x14(sp) ; optional
788 stwm r1,framesize(sp)
790 hpux cc functions look like:
792 stw rp,-0x14(sp) ; optional.
799 if (read_memory_integer (pc
, 4) == 0x6BC23FD9)
802 if (read_memory_integer (pc
, 4) == 0x8040241 &&
803 read_memory_integer (pc
+ 4, 4) == 0x81E0244)
809 find_dummy_frame_regs (frame
, frame_saved_regs
)
810 struct frame_info
*frame
;
811 struct frame_saved_regs
*frame_saved_regs
;
813 CORE_ADDR fp
= frame
->frame
;
816 frame_saved_regs
->regs
[RP_REGNUM
] = fp
- 20 & ~0x3;
817 frame_saved_regs
->regs
[FP_REGNUM
] = fp
;
818 frame_saved_regs
->regs
[1] = fp
+ 8;
819 frame_saved_regs
->regs
[3] = fp
+ 12;
820 for (fp
+= 16, i
= 3; i
< 30; fp
+= 4, i
++)
821 frame_saved_regs
->regs
[i
] = fp
;
822 frame_saved_regs
->regs
[31] = fp
;
824 for (i
= FP0_REGNUM
; i
< NUM_REGS
; i
++, fp
+= 8)
825 frame_saved_regs
->regs
[i
] = fp
;
826 /* depend on last increment of fp */
827 frame_saved_regs
->regs
[IPSW_REGNUM
] = fp
- 4;
828 frame_saved_regs
->regs
[SAR_REGNUM
] = fp
;
830 frame_saved_regs
->regs
[PCOQ_TAIL_REGNUM
] = fp
;
831 frame_saved_regs
->regs
[PCSQ_TAIL_REGNUM
] = fp
;
835 hp_push_arguments (nargs
, args
, sp
, struct_return
, struct_addr
)
840 CORE_ADDR struct_addr
;
842 /* array of arguments' offsets */
843 int *offset
= (int *)alloca(nargs
);
847 for (i
= 0; i
< nargs
; i
++)
849 cum
+= TYPE_LENGTH (VALUE_TYPE (args
[i
]));
850 /* value must go at proper alignment. Assume alignment is a
852 alignment
= hp_alignof (VALUE_TYPE (args
[i
]));
854 cum
= (cum
+ alignment
) & -alignment
;
857 for (i
== 0; i
< nargs
; i
++)
859 write_memory (sp
+ offset
[i
], VALUE_CONTENTS (args
[i
]), sizeof(int));
861 sp
+= min ((cum
+ 7) & -8, 48);
863 write_register (28, struct_addr
);
867 /* return the alignment of a type in bytes. Structures have the maximum
868 alignment required by their fields. */
874 int max_align
, align
, i
;
875 switch (TYPE_CODE (arg
))
880 return TYPE_LENGTH (arg
);
881 case TYPE_CODE_ARRAY
:
882 return hp_alignof (TYPE_FIELD_TYPE (arg
, 0));
883 case TYPE_CODE_STRUCT
:
884 case TYPE_CODE_UNION
:
886 for (i
= 0; i
< TYPE_NFIELDS (arg
); i
++)
888 /* Bit fields have no real alignment. */
889 if (!TYPE_FIELD_BITPOS (arg
, i
))
891 align
= hp_alignof (TYPE_FIELD_TYPE (arg
, i
));
892 max_align
= max (max_align
, align
);
901 /* Print the register regnum, or all registers if regnum is -1 */
903 pa_do_registers_info (regnum
, fpregs
)
907 char raw_regs
[REGISTER_BYTES
];
910 for (i
= 0; i
< NUM_REGS
; i
++)
911 read_relative_register_raw_bytes (i
, raw_regs
+ REGISTER_BYTE (i
));
913 pa_print_registers (raw_regs
, regnum
);
914 else if (regnum
< FP0_REGNUM
)
916 printf ("%s %x\n", reg_names
[regnum
], *(long *)(raw_regs
+
917 REGISTER_BYTE (regnum
)));
920 pa_print_fp_reg (regnum
);
923 pa_print_registers (raw_regs
, regnum
)
929 for (i
= 0; i
< 18; i
++)
930 printf ("%8.8s: %8x %8.8s: %8x %8.8s: %8x %8.8s: %8x\n",
932 *(int *)(raw_regs
+ REGISTER_BYTE (i
)),
934 *(int *)(raw_regs
+ REGISTER_BYTE (i
+ 18)),
936 *(int *)(raw_regs
+ REGISTER_BYTE (i
+ 36)),
938 *(int *)(raw_regs
+ REGISTER_BYTE (i
+ 54)));
939 for (i
= 72; i
< NUM_REGS
; i
++)
946 unsigned char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
947 unsigned char virtual_buffer
[MAX_REGISTER_VIRTUAL_SIZE
];
950 /* Get the data in raw format, then convert also to virtual format. */
951 read_relative_register_raw_bytes (i
, raw_buffer
);
952 REGISTER_CONVERT_TO_VIRTUAL (i
, raw_buffer
, virtual_buffer
);
954 fputs_filtered (reg_names
[i
], stdout
);
955 print_spaces_filtered (15 - strlen (reg_names
[i
]), stdout
);
957 val_print (REGISTER_VIRTUAL_TYPE (i
), virtual_buffer
, 0, stdout
, 0,
958 1, 0, Val_pretty_default
);
959 printf_filtered ("\n");
964 * Virtual to physical translation routines for Utah's Mach 3.0
966 #ifdef MACHKERNELDEBUG
970 #if 0 /* too many includes to resolve, too much crap */
971 #include <kern/queue.h>
973 #include <mach/vm_prot.h>
977 struct queue_entry
*next
; /* next element */
978 struct queue_entry
*prev
; /* previous element */
981 typedef struct queue_entry
*queue_t
;
982 typedef struct queue_entry queue_head_t
;
983 typedef struct queue_entry queue_chain_t
;
984 typedef struct queue_entry
*queue_entry_t
;
987 #define HP800_HASHSIZE 1024
988 #define HP800_HASHSIZE_LOG2 10
990 #define pmap_hash(space, offset) \
991 (((unsigned) (space) << 5 ^ \
992 ((unsigned) (offset) >> 19 | (unsigned) (space) << 13) ^ \
993 (unsigned) (offset) >> 11) & (HP800_HASHSIZE-1))
996 queue_head_t hash_link
; /* hash table links */
997 queue_head_t phys_link
; /* for mappings of a given PA */
998 space_t space
; /* virtual space */
999 unsigned offset
; /* virtual page number */
1000 unsigned tlbpage
; /* physical page (for TLB load) */
1001 unsigned tlbprot
; /* prot/access rights (for TLB load) */
1002 struct pmap
*pmap
; /* pmap mapping belongs to */
1006 queue_head_t phys_link
; /* head of mappings of a given PA */
1007 struct mapping
*writer
; /* mapping with R/W access */
1008 unsigned tlbprot
; /* TLB format protection */
1013 #define atop(a) ((unsigned)(a) >> 11)
1014 #define ptoa(p) ((unsigned)(p) << 11)
1015 #define trunc_page(a) ((unsigned)(a) & ~2047)
1017 STATIC
long equiv_end
;
1018 STATIC queue_head_t
*Ovtop_table
, *vtop_table
, *Ofree_mapping
, free_mapping
;
1019 STATIC
struct phys_entry
*Ophys_table
, *phys_table
;
1020 STATIC
long vm_last_phys
, vm_first_phys
;
1021 STATIC
struct mapping
*firstmap
, *lastmap
, *Omap_table
, *map_table
;
1022 STATIC
unsigned Omlow
, Omhigh
, Omhead
, Ovlow
, Ovhigh
, Oplow
, Ophigh
;
1023 STATIC
unsigned mlow
, mhigh
, mhead
, vlow
, vhigh
, plow
, phigh
;
1024 STATIC
int vtopsize
, physsize
, mapsize
;
1027 #define IS_OVTOPPTR(p) ((unsigned)(p) >= Ovlow && (unsigned)(p) < Ovhigh)
1028 #define IS_OMAPPTR(p) ((unsigned)(p) >= Omlow && (unsigned)(p) < Omhigh)
1029 #define IS_OPHYSPTR(p) ((unsigned)(p) >= Oplow && (unsigned)(p) < Ophigh)
1030 #define IS_VTOPPTR(p) ((unsigned)(p) >= vlow && (unsigned)(p) < vhigh)
1031 #define IS_MAPPTR(p) ((unsigned)(p) >= mlow && (unsigned)(p) < mhigh)
1032 #define IS_PHYSPTR(p) ((unsigned)(p) >= plow && (unsigned)(p) < phigh)
1058 "translate: may not be able to translate all addresses\n");
1062 mach_vtophys(space
, off
, pa
)
1063 unsigned space
, off
, *pa
;
1066 register queue_t qp
;
1067 register struct mapping
*mp
;
1071 * Kernel IO or equivilently mapped, one to one.
1073 if (space
== 0 && (long)off
< equiv_end
) {
1078 * Else look it up in specified space
1080 poff
= off
- trunc_page(off
);
1081 off
= trunc_page(off
);
1082 qp
= &vtop_table
[pmap_hash(space
, off
)];
1083 for (mp
= (struct mapping
*)qp
->next
;
1084 qp
!= (queue_entry_t
)mp
;
1085 mp
= (struct mapping
*)mp
->hash_link
.next
) {
1086 if (mp
->space
== space
&& mp
->offset
== off
) {
1087 *pa
= (mp
->tlbpage
<< 7) | poff
;
1097 char *tmp
, *mach_malloc();
1101 mach_read("equiv_end", ~0, (char *)&equiv_end
, sizeof equiv_end
);
1102 mach_read("vm_first_phys", ~0,
1103 (char *)&vm_first_phys
, sizeof vm_first_phys
);
1104 mach_read("vm_last_phys", ~0,
1105 (char *)&vm_last_phys
, sizeof vm_last_phys
);
1106 mach_read("firstmap", ~0, (char *)&firstmap
, sizeof firstmap
);
1107 mach_read("lastmap", ~0, (char *)&lastmap
, sizeof lastmap
);
1109 /* virtual to physical hash table */
1110 vtopsize
= HP800_HASHSIZE
;
1111 size
= vtopsize
* sizeof(queue_head_t
);
1112 tmp
= mach_malloc("vtop table", size
);
1113 mach_read("vtop_table", ~0, (char *)&Ovtop_table
, sizeof Ovtop_table
);
1114 mach_read("vtop table", (CORE_ADDR
)Ovtop_table
, tmp
, size
);
1115 vtop_table
= (queue_head_t
*) tmp
;
1117 /* inverted page table */
1118 physsize
= atop(vm_last_phys
- vm_first_phys
);
1119 size
= physsize
* sizeof(struct phys_entry
);
1120 tmp
= mach_malloc("phys table", size
);
1121 mach_read("phys_table", ~0, (char *)&Ophys_table
, sizeof Ophys_table
);
1122 mach_read("phys table", (CORE_ADDR
)Ophys_table
, tmp
, size
);
1123 phys_table
= (struct phys_entry
*) tmp
;
1125 /* mapping structures */
1126 Ofree_mapping
= (queue_head_t
*) ksym_lookup("free_mapping");
1127 mach_read("free mapping", (CORE_ADDR
)Ofree_mapping
,
1128 (char *) &free_mapping
, sizeof free_mapping
);
1129 Omap_table
= firstmap
;
1130 mapsize
= lastmap
- firstmap
;
1131 size
= mapsize
* sizeof(struct mapping
);
1132 tmp
= mach_malloc("mapping table", size
);
1133 mach_read("mapping table", (CORE_ADDR
)Omap_table
, tmp
, size
);
1134 map_table
= (struct mapping
*) tmp
;
1137 Ovlow
= (unsigned) Ovtop_table
;
1138 Ovhigh
= (unsigned) &Ovtop_table
[vtopsize
];
1139 Oplow
= (unsigned) Ophys_table
;
1140 Ophigh
= (unsigned) &Ophys_table
[physsize
];
1141 Omhead
= (unsigned) Ofree_mapping
;
1142 Omlow
= (unsigned) firstmap
;
1143 Omhigh
= (unsigned) lastmap
;
1144 mlow
= (unsigned) map_table
;
1145 mhigh
= (unsigned) &map_table
[mapsize
];
1146 mhead
= (unsigned) &free_mapping
;
1147 vlow
= (unsigned) vtop_table
;
1148 vhigh
= (unsigned) &vtop_table
[vtopsize
];
1149 plow
= (unsigned) phys_table
;
1150 phigh
= (unsigned) &phys_table
[physsize
];
1153 fprintf(stderr
, "Ovtop [%#x-%#x) Ophys [%#x-%#x) Omap %#x [%#x-%#x)\n",
1154 Ovlow
, Ovhigh
, Oplow
, Ophigh
, Omhead
, Omlow
, Omhigh
);
1155 fprintf(stderr
, "vtop [%#x-%#x) phys [%#x-%#x) map %#x [%#x-%#x)\n",
1156 vlow
, vhigh
, plow
, phigh
, mhead
, mlow
, mhigh
);
1158 return(adjustdata());
1171 } else if (IS_OVTOPPTR(ptr
)) {
1172 ret
= vlow
+ (ptr
- Ovlow
);
1174 } else if (IS_OPHYSPTR(ptr
)) {
1175 ret
= plow
+ (ptr
- Oplow
);
1177 } else if (IS_OMAPPTR(ptr
)) {
1178 ret
= mlow
+ (ptr
- Omlow
);
1180 } else if (ptr
== Omhead
) {
1184 error("bogus pointer %#x", ptr
);
1189 fprintf(stderr
, "%x (%s) -> %x\n", ptr
, str
, ret
);
1197 register int i
, lim
;
1199 struct phys_entry
*np
;
1204 for (nq
= vtop_table
; nq
< &vtop_table
[lim
]; nq
++) {
1205 nq
->next
= (queue_entry_t
) ptrcvt((unsigned)nq
->next
);
1206 nq
->prev
= (queue_entry_t
) ptrcvt((unsigned)nq
->prev
);
1211 for (np
= phys_table
; np
< &phys_table
[lim
]; np
++) {
1212 np
->phys_link
.next
= (queue_entry_t
)
1213 ptrcvt((unsigned)np
->phys_link
.next
);
1214 np
->phys_link
.prev
= (queue_entry_t
)
1215 ptrcvt((unsigned)np
->phys_link
.prev
);
1216 np
->writer
= (struct mapping
*) ptrcvt((unsigned)np
->writer
);
1220 free_mapping
.next
= (queue_entry_t
)ptrcvt((unsigned)free_mapping
.next
);
1221 free_mapping
.prev
= (queue_entry_t
)ptrcvt((unsigned)free_mapping
.prev
);
1223 for (nm
= map_table
; nm
< &map_table
[lim
]; nm
++) {
1224 nm
->hash_link
.next
= (queue_entry_t
)
1225 ptrcvt((unsigned)nm
->hash_link
.next
);
1226 nm
->hash_link
.prev
= (queue_entry_t
)
1227 ptrcvt((unsigned)nm
->hash_link
.prev
);
1228 nm
->phys_link
.next
= (queue_entry_t
)
1229 ptrcvt((unsigned)nm
->phys_link
.next
);
1230 nm
->phys_link
.prev
= (queue_entry_t
)
1231 ptrcvt((unsigned)nm
->phys_link
.prev
);
1237 * Consistency checks, make sure:
1239 * 1. all mappings are accounted for
1241 * 3. no wild pointers
1242 * 4. consisent TLB state
1247 register struct mapstate
*ms
;
1251 mapstate
= (struct mapstate
*)
1252 mach_malloc("map state", mapsize
* sizeof(struct mapstate
));
1253 for (ms
= mapstate
; ms
< &mapstate
[mapsize
]; ms
++) {
1255 ms
->hashix
= ms
->physix
= -2;
1259 * Check the free list
1261 checkhashchain(&free_mapping
, M_ISFREE
, -1);
1263 * Check every hash chain
1265 for (i
= 0; i
< vtopsize
; i
++)
1266 checkhashchain(&vtop_table
[i
], M_ISHASH
, i
);
1268 * Check every phys chain
1270 for (i
= 0; i
< physsize
; i
++)
1271 checkphyschain(&phys_table
[i
].phys_link
, M_ISPHYS
, i
);
1273 * Cycle through mapstate looking for anomolies
1276 for (i
= 0; i
< mapsize
; i
++) {
1277 switch (ms
->flags
) {
1279 case M_ISHASH
|M_ISPHYS
:
1282 merror(ms
, "not found");
1286 merror(ms
, "in vtop but not phys");
1290 merror(ms
, "in phys but not vtop");
1294 merror(ms
, "totally bogus");
1300 return(errors
? 0 : 1);
1304 checkhashchain(qhp
, flag
, ix
)
1307 register queue_entry_t qp
, pqp
;
1308 register struct mapping
*mp
;
1309 struct mapstate
*ms
;
1313 * First element is not a mapping structure,
1314 * chain must be empty.
1316 if (!IS_MAPPTR(qp
)) {
1317 if (qp
!= qhp
|| qp
!= qhp
->prev
)
1318 fatal("bad vtop_table header pointer");
1322 mp
= (struct mapping
*) qp
;
1323 qp
= &mp
->hash_link
;
1324 if (qp
->prev
!= pqp
)
1325 fatal("bad hash_link prev pointer");
1326 ms
= &mapstate
[mp
-map_table
];
1329 pqp
= (queue_entry_t
) mp
;
1331 } while (IS_MAPPTR(qp
));
1333 fatal("bad hash_link next pointer");
1338 checkphyschain(qhp
, flag
, ix
)
1341 register queue_entry_t qp
, pqp
;
1342 register struct mapping
*mp
;
1343 struct mapstate
*ms
;
1347 * First element is not a mapping structure,
1348 * chain must be empty.
1350 if (!IS_MAPPTR(qp
)) {
1351 if (qp
!= qhp
|| qp
!= qhp
->prev
)
1352 fatal("bad phys_table header pointer");
1356 mp
= (struct mapping
*) qp
;
1357 qp
= &mp
->phys_link
;
1358 if (qp
->prev
!= pqp
)
1359 fatal("bad phys_link prev pointer");
1360 ms
= &mapstate
[mp
-map_table
];
1363 pqp
= (queue_entry_t
) mp
;
1365 } while (IS_MAPPTR(qp
));
1367 fatal("bad phys_link next pointer");
1373 struct mapstate
*ms
;
1379 "vtophys: %s: %c%c%c, hashix %d, physix %d, mapping %x\n",
1381 (ms
->flags
& M_ISFREE
) ? 'F' : '-',
1382 (ms
->flags
& M_ISHASH
) ? 'H' : '-',
1383 (ms
->flags
& M_ISPHYS
) ? 'P' : '-',
1384 ms
->hashix
, ms
->physix
, &map_table
[ms
-mapstate
]);
1385 return_to_top_level();
1389 mach_read(str
, from
, top
, size
)
1398 from
= ksym_lookup(str
);
1399 paddr
= vtophys(0, from
);
1400 if (paddr
== ~0 || physrd(paddr
, top
, size
) != 0)
1401 fatal("cannot read %s", str
);
1405 mach_malloc(str
, size
)
1409 char *ptr
= (char *) malloc(size
);
1412 fatal("no memory for %s", str
);
1419 _initialize_hp9k8_dep()
1421 add_com ("process-address", class_obscure
, set_paddr_command
,
1422 "The process identified by (ps-style) ADDR becomes the\n\
1423 \"current\" process context for kernel debugging.");
1424 add_com_alias ("paddr", "process-address", class_obscure
, 0);
1425 add_com ("virtual-to-physical", class_obscure
, vtop_command
,
1426 "Translates the kernel virtual address ADDR into a physical address.");
1427 add_com_alias ("vtop", "virtual-to-physical", class_obscure
, 0);