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 <sys/ptrace.h>
54 #include <machine/psl.h>
57 #include <sys/vmmac.h>
58 #include <machine/machparam.h>
59 #include <machine/vmparam.h>
60 #include <machine/pde.h>
61 #include <machine/cpu.h>
62 #include <machine/iomod.h>
63 #include <machine/pcb.h>
64 #include <machine/rpb.h>
67 extern int kernel_debugging
;
68 extern CORE_ADDR startup_file_start
;
69 extern CORE_ADDR startup_file_end
;
71 #define KERNOFF ((unsigned)KERNBASE)
72 #define INKERNEL(x) ((x) >= KERNOFF && (x) < KERNOFF + ctob(slr))
74 static int ok_to_cache();
75 static void set_kernel_boundaries();
78 int vtophys_ready
= 0;
94 /* Last modification time of executable file.
95 Also used in source.c to compare against mtime of a source file. */
97 extern int exec_mtime
;
99 /* Virtual addresses of bounds of the two areas of memory in the core file. */
101 /* extern CORE_ADDR data_start; */
102 extern CORE_ADDR data_end
;
103 extern CORE_ADDR stack_start
;
104 extern CORE_ADDR stack_end
;
106 /* Virtual addresses of bounds of two areas of memory in the exec file.
107 Note that the data area in the exec file is used only when there is no core file. */
109 extern CORE_ADDR text_start
;
110 extern CORE_ADDR text_end
;
112 extern CORE_ADDR exec_data_start
;
113 extern CORE_ADDR exec_data_end
;
115 /* Address in executable file of start of text area data. */
117 extern int text_offset
;
119 /* Address in executable file of start of data area data. */
121 extern int exec_data_offset
;
123 /* Address in core file of start of data area data. */
125 extern int data_offset
;
127 /* Address in core file of start of stack area data. */
129 extern int stack_offset
;
131 struct header file_hdr
;
132 struct som_exec_auxhdr exec_hdr
;
136 * Kernel debugging routines.
139 static struct pcb pcb
;
140 static struct pde
*pdir
;
141 static struct hte
*htbl
;
142 static u_int npdir
, nhtbl
;
151 if ((i
= lookup_misc_func(name
)) < 0)
152 error("kernel symbol `%s' not found.", name
);
154 return (misc_function_vector
[i
].address
);
158 * (re-)set the variables that tell "inside_entry_file" where to end
162 set_kernel_boundaries()
164 switch (kerneltype
) {
166 startup_file_start
= ksym_lookup("$syscall");
167 startup_file_end
= ksym_lookup("trap");
170 startup_file_start
= ksym_lookup("syscallinit");
171 startup_file_end
= ksym_lookup("$syscallexit");
177 * return true if 'len' bytes starting at 'addr' can be read out as
178 * longwords and/or locally cached (this is mostly for memory mapped
179 * i/o register access when debugging remote kernels).
182 ok_to_cache(addr
, len
)
184 static CORE_ADDR ioptr
;
187 ioptr
= ksym_lookup("ioptr");
189 if (addr
>= ioptr
&& addr
< SPA_HIGH
)
196 physrd(addr
, dat
, len
)
200 if (lseek(corechan
, addr
, L_SET
) == -1)
202 if (read(corechan
, dat
, len
) != len
)
209 * When looking at kernel data space through /dev/mem or with a core file, do
210 * virtual memory mapping.
218 u_int hindx
, vpageno
, ppageno
;
221 if (!vtophys_ready
) {
222 phys
= addr
; /* XXX for kvread */
223 } else if (kerneltype
== OS_BSD
) {
224 /* make offset into a virtual page no */
225 vpageno
= btop(addr
);
227 * Determine index into hash table, initialize pptr to this
228 * entry (since first word of pte & hte are same), and set
229 * physical page number for first entry in chain.
231 hindx
= pdirhash(space
, addr
) & (nhtbl
-1);
232 pptr
= (struct pde
*) &htbl
[hindx
];
233 ppageno
= pptr
->pde_next
;
237 pptr
= &pdir
[ppageno
];
239 * If space id & virtual page number match, return
240 * "next PDIR entry of previous PDIR entry" as the
241 * physical page or'd with offset into page.
243 if (pptr
->pde_space
== space
&&
244 pptr
->pde_page
== vpageno
) {
245 phys
= (CORE_ADDR
) ((u_int
)ptob(ppageno
) |
249 ppageno
= pptr
->pde_next
;
252 #ifdef MACHKERNELDEBUG
253 else if (kerneltype
== OS_MACH
) {
254 mach_vtophys(space
, addr
, &phys
);
258 printf("vtophys(%x.%x) -> %x\n", space
, addr
, phys
);
269 paddr
= vtophys(0, addr
);
271 if (physrd(paddr
, (char *)&addr
, sizeof(addr
)) == 0)
282 extern char registers
[];
283 static int reg2pcb
[] = {
285 -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
286 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
287 45, 52, 51, 75, 74, 49, 53, 54, 55, 56, -1, 70, 66, 67, 68, 69,
288 71, 72, 73, 34, 42, 43, 44, 46, 47, 58, 59, 60, -1, -1, -1, -1,
289 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
292 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
293 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
294 43, 64, 67, 68, 67, 47, 51, 52, 53, 54, -1, 35, 31, 32, 33, 34,
295 36, 37, 38, 39, 40, 41, 42, 44, 45, 56, 57, 58,102,103,104, -1,
296 70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 82, 84, 86, 88, 90, 92,
299 -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
300 14, 15, 16, -1, -1, -1, -1, -1, -1, -1, -1, 17, -1, -1, 18, -1,
301 25, -1, -1, -1, -1, 30, -1, -1, -1, -1, -1, 20, -1, -1, -1, 19,
302 21, 22, 23, 24, 26, 27, -1, 28, 29, -1, -1, -1, -1, -1, -1, -1,
303 34, 35, 36, 37, 38, 39, 40, 41, -1, -1, -1, -1, -1, -1, -1, -1,
306 static struct rpb
*rpbaddr
= (struct rpb
*) 0;
307 static u_int rpbpcbaddr
= 0;
309 if (!remote_debugging
) {
311 * If we are debugging a post-mortem and this is the first
312 * call of read_pcb, read the RPB. Also assoicate the
313 * thread/proc running at the time with the RPB.
315 if (!devmem
&& rpbpcbaddr
== 0) {
316 CORE_ADDR raddr
= ksym_lookup("rpb");
320 rpbaddr
= (struct rpb
*) malloc(sizeof *rpbaddr
);
321 if (!physrd(raddr
, (char *)rpbaddr
, sizeof *rpbaddr
)) {
327 error("cannot read rpb, using pcb for registers\n");
329 free((char *)rpbaddr
);
333 if (physrd (addr
, (char *)&pcb
, sizeof pcb
))
334 error ("cannot read pcb at %x.\n", addr
);
336 if (remote_read_inferior_memory(addr
, (char *)&pcb
, sizeof pcb
))
337 error ("cannot read pcb at %x.\n", addr
);
340 if (kerneltype
== OS_BSD
) {
341 printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n",
342 pcb
.pcb_p0br
, pcb
.pcb_p0lr
, pcb
.pcb_p1br
, pcb
.pcb_p1lr
);
345 printf("pcb %lx psw %lx ksp %lx\n",
346 addr
, ((int *)&pcb
)[31], ((int *)&pcb
)[32]);
350 * get the register values out of the sys pcb and
351 * store them where `read_register' will find them.
353 bzero(registers
, REGISTER_BYTES
);
354 for (i
= 0; i
< NUM_REGS
; ++i
)
355 if (reg2pcb
[i
+off
] != -1)
356 supply_register(i
, &((int *)&pcb
)[reg2pcb
[i
+off
]]);
358 * If the RPB is valid for this thread/proc use the register values
361 if (addr
== rpbpcbaddr
) {
363 for (i
= 0; i
< NUM_REGS
; ++i
)
364 if (reg2pcb
[i
+off
] != -1)
365 supply_register(i
, &((int *)rpbaddr
)[reg2pcb
[i
+off
]]);
370 setup_kernel_debugging()
375 fstat(corechan
, &stb
);
377 if ((stb
.st_mode
& S_IFMT
) == S_IFCHR
&& stb
.st_rdev
== makedev(2, 0))
381 if (lookup_misc_func("Sysmap") < 0)
382 kerneltype
= OS_MACH
;
386 if (kerneltype
== OS_BSD
) {
390 * Hash table and PDIR are equivalently mapped
392 nhtbl
= kvread(ksym_lookup("nhtbl"));
394 len
= nhtbl
* sizeof(*htbl
);
395 htbl
= (struct hte
*) malloc(len
);
397 addr
= kvread(ksym_lookup("htbl"));
398 if (physrd(addr
, (char *)htbl
, len
))
404 npdir
= kvread(ksym_lookup("npdir"));
406 len
= npdir
* sizeof(*pdir
);
407 pdir
= (struct pde
*) malloc(len
);
409 addr
= kvread(ksym_lookup("pdir"));
410 if (physrd(addr
, (char *)pdir
, len
))
417 error("cannot read PDIR/HTBL");
423 * pcb where "panic" saved registers in first thing in
424 * current u-area. The current u-area is pointed to by
427 addr
= kvread(ksym_lookup("uptr"));
429 error("cannot read current u-area address");
432 read_pcb(vtophys(0, addr
)); /* XXX space */
434 /* find stack frame */
439 panicstr
= kvread(ksym_lookup("panicstr"));
442 kernel_core_file_hook(panicstr
, buf
, sizeof(buf
));
443 for (cp
= buf
; cp
< &buf
[sizeof(buf
)] && *cp
; cp
++)
444 if (!isascii(*cp
) || (!isprint(*cp
) && !isspace(*cp
)))
448 printf("panic: %s\n", buf
);
451 #ifdef MACHKERNELDEBUG
456 * Set up address translation
458 if (mach_vtophys_init() == 0) {
459 error("cannot initialize vtophys for Mach");
465 * Locate active thread and read PCB
467 * - assumes uni-processor
468 * - assumes position of pcb to avoid mach includes
470 thread
= (int *)kvread(ksym_lookup("active_threads"));
471 addr
= kvread(&thread
[9]); /* XXX: pcb addr */
472 read_pcb(vtophys(0, addr
));
483 error_no_arg("kernel virtual address");
484 if (!kernel_debugging
)
485 error("not debugging kernel");
488 off
= (u_int
) parse_and_eval_address(arg
);
489 pa
= vtophys(sp
, off
);
490 printf("%lx.%lx -> ", sp
, off
);
492 printf("<invalid>\n");
497 set_paddr_command(arg
)
503 if (kerneltype
== OS_BSD
)
504 error_no_arg("ps-style address for new process");
506 error_no_arg("thread structure virtual address");
508 if (!kernel_debugging
)
509 error("not debugging kernel");
511 addr
= (u_int
) parse_and_eval_address(arg
);
512 if (kerneltype
== OS_BSD
)
515 addr
= kvread(&(((int *)addr
)[9])); /* XXX: pcb addr */
516 addr
= vtophys(0, addr
); /* XXX space */
520 flush_cached_frames();
521 set_current_frame(create_new_frame(read_register(FP_REGNUM
), read_pc()));
522 select_frame(get_current_frame(), 0);
526 * read len bytes from kernel virtual address 'addr' into local
527 * buffer 'buf'. Return 0 if read ok, 1 otherwise. On read
528 * errors, portion of buffer not read is zeroed.
530 kernel_core_file_hook(addr
, buf
, len
)
539 paddr
= vtophys(0, addr
); /* XXX space */
544 /* we can't read across a page boundary */
545 i
= min(len
, NBPG
- (addr
& PGOFSET
));
546 if (physrd(paddr
, buf
, i
)) {
563 /* Routines to extract various sized constants out of hppa
566 /* This assumes that no garbage lies outside of the lower bits of
570 sign_extend (val
, bits
)
573 return (int)(val
>> bits
- 1 ? (-1 << bits
) | val
: val
);
576 /* For many immediate values the sign bit is the low bit! */
579 low_sign_extend (val
, bits
)
582 return (int)((val
& 0x1 ? (-1 << (bits
- 1)) : 0) | val
>> 1);
584 /* extract the immediate field from a ld{bhw}s instruction */
589 get_field (val
, from
, to
)
590 unsigned val
, from
, to
;
592 val
= val
>> 31 - to
;
593 return val
& ((1 << 32 - from
) - 1);
597 set_field (val
, from
, to
, new_val
)
598 unsigned *val
, from
, to
;
600 unsigned mask
= ~((1 << (to
- from
+ 1)) << (31 - from
));
601 return *val
= *val
& mask
| (new_val
<< (31 - from
));
604 /* extract a 3-bit space register number from a be, ble, mtsp or mfsp */
609 return GET_FIELD (word
, 18, 18) << 2 | GET_FIELD (word
, 16, 17);
612 extract_5_load (word
)
615 return low_sign_extend (word
>> 16 & MASK_5
, 5);
618 /* extract the immediate field from a st{bhw}s instruction */
621 extract_5_store (word
)
624 return low_sign_extend (word
& MASK_5
, 5);
627 /* extract an 11 bit immediate field */
633 return low_sign_extend (word
& MASK_11
, 11);
636 /* extract a 14 bit immediate field */
642 return low_sign_extend (word
& MASK_14
, 14);
645 /* deposit a 14 bit constant in a word */
648 deposit_14 (opnd
, word
)
652 unsigned sign
= (opnd
< 0 ? 1 : 0);
654 return word
| ((unsigned)opnd
<< 1 & MASK_14
) | sign
;
657 /* extract a 21 bit constant */
667 val
= GET_FIELD (word
, 20, 20);
669 val
|= GET_FIELD (word
, 9, 19);
671 val
|= GET_FIELD (word
, 5, 6);
673 val
|= GET_FIELD (word
, 0, 4);
675 val
|= GET_FIELD (word
, 7, 8);
676 return sign_extend (val
, 21) << 11;
679 /* deposit a 21 bit constant in a word. Although 21 bit constants are
680 usually the top 21 bits of a 32 bit constant, we assume that only
681 the low 21 bits of opnd are relevant */
684 deposit_21 (opnd
, word
)
689 val
|= GET_FIELD (opnd
, 11 + 14, 11 + 18);
691 val
|= GET_FIELD (opnd
, 11 + 12, 11 + 13);
693 val
|= GET_FIELD (opnd
, 11 + 19, 11 + 20);
695 val
|= GET_FIELD (opnd
, 11 + 1, 11 + 11);
697 val
|= GET_FIELD (opnd
, 11 + 0, 11 + 0);
701 /* extract a 12 bit constant from branch instructions */
707 return sign_extend (GET_FIELD (word
, 19, 28) |
708 GET_FIELD (word
, 29, 29) << 10 |
709 (word
& 0x1) << 11, 12) << 2;
712 /* extract a 17 bit constant from branch instructions, returning the
713 19 bit signed value. */
719 return sign_extend (GET_FIELD (word
, 19, 28) |
720 GET_FIELD (word
, 29, 29) << 10 |
721 GET_FIELD (word
, 11, 15) << 11 |
722 (word
& 0x1) << 16, 17) << 2;
727 frame_saved_pc (frame
)
730 if (get_current_frame () == frame
)
732 struct frame_saved_regs saved_regs
;
733 CORE_ADDR pc
= get_frame_pc (frame
);
735 get_frame_saved_regs (frame
, &saved_regs
);
736 if (pc
>= millicode_start
&& pc
< millicode_end
)
737 return read_register (31);
738 else if (saved_regs
.regs
[RP_REGNUM
])
739 return read_memory_integer (saved_regs
.regs
[RP_REGNUM
], 4);
741 return read_register (RP_REGNUM
);
743 return read_memory_integer (frame
->frame
- 20, 4) & ~0x3;
747 /* To see if a frame chain is valid, see if the caller looks like it
748 was compiled with gcc. */
750 int frame_chain_valid (chain
, thisframe
)
754 if (chain
&& (chain
> 0x60000000
755 /* || remote_debugging -this is no longer used */
761 CORE_ADDR pc
= get_pc_function_start (FRAME_SAVED_PC (thisframe
));
763 if (!inside_entry_file (pc
))
765 /* look for stw rp, -20(0,sp); copy 4,1; copy sp, 4 */
766 if (read_memory_integer (pc
, 4) == 0x6BC23FD9)
769 if (read_memory_integer (pc
, 4) == 0x8040241 &&
770 read_memory_integer (pc
+ 4, 4) == 0x81E0244)
779 /* Some helper functions. gcc_p returns 1 if the function beginning at
780 pc appears to have been compiled with gcc. hpux_cc_p returns 1 if
781 fn was compiled with hpux cc. gcc functions look like :
783 stw rp,-0x14(sp) ; optional
786 stwm r1,framesize(sp)
788 hpux cc functions look like:
790 stw rp,-0x14(sp) ; optional.
797 if (read_memory_integer (pc
, 4) == 0x6BC23FD9)
800 if (read_memory_integer (pc
, 4) == 0x8040241 &&
801 read_memory_integer (pc
+ 4, 4) == 0x81E0244)
807 find_dummy_frame_regs (frame
, frame_saved_regs
)
808 struct frame_info
*frame
;
809 struct frame_saved_regs
*frame_saved_regs
;
811 CORE_ADDR fp
= frame
->frame
;
814 frame_saved_regs
->regs
[RP_REGNUM
] = fp
- 20 & ~0x3;
815 frame_saved_regs
->regs
[FP_REGNUM
] = fp
;
816 frame_saved_regs
->regs
[1] = fp
+ 8;
817 frame_saved_regs
->regs
[3] = fp
+ 12;
818 for (fp
+= 16, i
= 3; i
< 30; fp
+= 4, i
++)
819 frame_saved_regs
->regs
[i
] = fp
;
820 frame_saved_regs
->regs
[31] = fp
;
822 for (i
= FP0_REGNUM
; i
< NUM_REGS
; i
++, fp
+= 8)
823 frame_saved_regs
->regs
[i
] = fp
;
824 /* depend on last increment of fp */
825 frame_saved_regs
->regs
[IPSW_REGNUM
] = fp
- 4;
826 frame_saved_regs
->regs
[SAR_REGNUM
] = fp
;
828 frame_saved_regs
->regs
[PCOQ_TAIL_REGNUM
] = fp
;
829 frame_saved_regs
->regs
[PCSQ_TAIL_REGNUM
] = fp
;
833 hp_push_arguments (nargs
, args
, sp
, struct_return
, struct_addr
)
838 CORE_ADDR struct_addr
;
840 /* array of arguments' offsets */
841 int *offset
= (int *)alloca(nargs
);
845 for (i
= 0; i
< nargs
; i
++)
847 cum
+= TYPE_LENGTH (VALUE_TYPE (args
[i
]));
848 /* value must go at proper alignment. Assume alignment is a
850 alignment
= hp_alignof (VALUE_TYPE (args
[i
]));
852 cum
= (cum
+ alignment
) & -alignment
;
855 for (i
== 0; i
< nargs
; i
++)
857 write_memory (sp
+ offset
[i
], VALUE_CONTENTS (args
[i
]), sizeof(int));
859 sp
+= min ((cum
+ 7) & -8, 48);
861 write_register (28, struct_addr
);
865 /* return the alignment of a type in bytes. Structures have the maximum
866 alignment required by their fields. */
872 int max_align
, align
, i
;
873 switch (TYPE_CODE (arg
))
878 return TYPE_LENGTH (arg
);
879 case TYPE_CODE_ARRAY
:
880 return hp_alignof (TYPE_FIELD_TYPE (arg
, 0));
881 case TYPE_CODE_STRUCT
:
882 case TYPE_CODE_UNION
:
884 for (i
= 0; i
< TYPE_NFIELDS (arg
); i
++)
886 /* Bit fields have no real alignment. */
887 if (!TYPE_FIELD_BITPOS (arg
, i
))
889 align
= hp_alignof (TYPE_FIELD_TYPE (arg
, i
));
890 max_align
= max (max_align
, align
);
899 /* Print the register regnum, or all registers if regnum is -1 */
901 pa_do_registers_info (regnum
, fpregs
)
905 char raw_regs
[REGISTER_BYTES
];
908 for (i
= 0; i
< NUM_REGS
; i
++)
909 read_relative_register_raw_bytes (i
, raw_regs
+ REGISTER_BYTE (i
));
911 pa_print_registers (raw_regs
, regnum
);
912 else if (regnum
< FP0_REGNUM
)
914 printf ("%s %x\n", reg_names
[regnum
], *(long *)(raw_regs
+
915 REGISTER_BYTE (regnum
)));
918 pa_print_fp_reg (regnum
);
921 pa_print_registers (raw_regs
, regnum
)
927 for (i
= 0; i
< 18; i
++)
928 printf ("%8.8s: %8x %8.8s: %8x %8.8s: %8x %8.8s: %8x\n",
930 *(int *)(raw_regs
+ REGISTER_BYTE (i
)),
932 *(int *)(raw_regs
+ REGISTER_BYTE (i
+ 18)),
934 *(int *)(raw_regs
+ REGISTER_BYTE (i
+ 36)),
936 *(int *)(raw_regs
+ REGISTER_BYTE (i
+ 54)));
937 for (i
= 72; i
< NUM_REGS
; i
++)
944 unsigned char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
945 unsigned char virtual_buffer
[MAX_REGISTER_VIRTUAL_SIZE
];
948 /* Get the data in raw format, then convert also to virtual format. */
949 read_relative_register_raw_bytes (i
, raw_buffer
);
950 REGISTER_CONVERT_TO_VIRTUAL (i
, raw_buffer
, virtual_buffer
);
952 fputs_filtered (reg_names
[i
], stdout
);
953 print_spaces_filtered (15 - strlen (reg_names
[i
]), stdout
);
955 val_print (REGISTER_VIRTUAL_TYPE (i
), virtual_buffer
, 0, stdout
, 0,
956 1, 0, Val_pretty_default
);
957 printf_filtered ("\n");
962 * Virtual to physical translation routines for Utah's Mach 3.0
964 #ifdef MACHKERNELDEBUG
968 #if 0 /* too many includes to resolve, too much crap */
969 #include <kern/queue.h>
971 #include <mach/vm_prot.h>
975 struct queue_entry
*next
; /* next element */
976 struct queue_entry
*prev
; /* previous element */
979 typedef struct queue_entry
*queue_t
;
980 typedef struct queue_entry queue_head_t
;
981 typedef struct queue_entry queue_chain_t
;
982 typedef struct queue_entry
*queue_entry_t
;
985 #define HP800_HASHSIZE 1024
986 #define HP800_HASHSIZE_LOG2 10
988 #define pmap_hash(space, offset) \
989 (((unsigned) (space) << 5 ^ \
990 ((unsigned) (offset) >> 19 | (unsigned) (space) << 13) ^ \
991 (unsigned) (offset) >> 11) & (HP800_HASHSIZE-1))
994 queue_head_t hash_link
; /* hash table links */
995 queue_head_t phys_link
; /* for mappings of a given PA */
996 space_t space
; /* virtual space */
997 unsigned offset
; /* virtual page number */
998 unsigned tlbpage
; /* physical page (for TLB load) */
999 unsigned tlbprot
; /* prot/access rights (for TLB load) */
1000 struct pmap
*pmap
; /* pmap mapping belongs to */
1004 queue_head_t phys_link
; /* head of mappings of a given PA */
1005 struct mapping
*writer
; /* mapping with R/W access */
1006 unsigned tlbprot
; /* TLB format protection */
1011 #define atop(a) ((unsigned)(a) >> 11)
1012 #define ptoa(p) ((unsigned)(p) << 11)
1013 #define trunc_page(a) ((unsigned)(a) & ~2047)
1015 STATIC
long equiv_end
;
1016 STATIC queue_head_t
*Ovtop_table
, *vtop_table
, *Ofree_mapping
, free_mapping
;
1017 STATIC
struct phys_entry
*Ophys_table
, *phys_table
;
1018 STATIC
long vm_last_phys
, vm_first_phys
;
1019 STATIC
struct mapping
*firstmap
, *lastmap
, *Omap_table
, *map_table
;
1020 STATIC
unsigned Omlow
, Omhigh
, Omhead
, Ovlow
, Ovhigh
, Oplow
, Ophigh
;
1021 STATIC
unsigned mlow
, mhigh
, mhead
, vlow
, vhigh
, plow
, phigh
;
1022 STATIC
int vtopsize
, physsize
, mapsize
;
1025 #define IS_OVTOPPTR(p) ((unsigned)(p) >= Ovlow && (unsigned)(p) < Ovhigh)
1026 #define IS_OMAPPTR(p) ((unsigned)(p) >= Omlow && (unsigned)(p) < Omhigh)
1027 #define IS_OPHYSPTR(p) ((unsigned)(p) >= Oplow && (unsigned)(p) < Ophigh)
1028 #define IS_VTOPPTR(p) ((unsigned)(p) >= vlow && (unsigned)(p) < vhigh)
1029 #define IS_MAPPTR(p) ((unsigned)(p) >= mlow && (unsigned)(p) < mhigh)
1030 #define IS_PHYSPTR(p) ((unsigned)(p) >= plow && (unsigned)(p) < phigh)
1056 "translate: may not be able to translate all addresses\n");
1060 mach_vtophys(space
, off
, pa
)
1061 unsigned space
, off
, *pa
;
1064 register queue_t qp
;
1065 register struct mapping
*mp
;
1069 * Kernel IO or equivilently mapped, one to one.
1071 if (space
== 0 && (long)off
< equiv_end
) {
1076 * Else look it up in specified space
1078 poff
= off
- trunc_page(off
);
1079 off
= trunc_page(off
);
1080 qp
= &vtop_table
[pmap_hash(space
, off
)];
1081 for (mp
= (struct mapping
*)qp
->next
;
1082 qp
!= (queue_entry_t
)mp
;
1083 mp
= (struct mapping
*)mp
->hash_link
.next
) {
1084 if (mp
->space
== space
&& mp
->offset
== off
) {
1085 *pa
= (mp
->tlbpage
<< 7) | poff
;
1095 char *tmp
, *mach_malloc();
1099 mach_read("equiv_end", ~0, (char *)&equiv_end
, sizeof equiv_end
);
1100 mach_read("vm_first_phys", ~0,
1101 (char *)&vm_first_phys
, sizeof vm_first_phys
);
1102 mach_read("vm_last_phys", ~0,
1103 (char *)&vm_last_phys
, sizeof vm_last_phys
);
1104 mach_read("firstmap", ~0, (char *)&firstmap
, sizeof firstmap
);
1105 mach_read("lastmap", ~0, (char *)&lastmap
, sizeof lastmap
);
1107 /* virtual to physical hash table */
1108 vtopsize
= HP800_HASHSIZE
;
1109 size
= vtopsize
* sizeof(queue_head_t
);
1110 tmp
= mach_malloc("vtop table", size
);
1111 mach_read("vtop_table", ~0, (char *)&Ovtop_table
, sizeof Ovtop_table
);
1112 mach_read("vtop table", (CORE_ADDR
)Ovtop_table
, tmp
, size
);
1113 vtop_table
= (queue_head_t
*) tmp
;
1115 /* inverted page table */
1116 physsize
= atop(vm_last_phys
- vm_first_phys
);
1117 size
= physsize
* sizeof(struct phys_entry
);
1118 tmp
= mach_malloc("phys table", size
);
1119 mach_read("phys_table", ~0, (char *)&Ophys_table
, sizeof Ophys_table
);
1120 mach_read("phys table", (CORE_ADDR
)Ophys_table
, tmp
, size
);
1121 phys_table
= (struct phys_entry
*) tmp
;
1123 /* mapping structures */
1124 Ofree_mapping
= (queue_head_t
*) ksym_lookup("free_mapping");
1125 mach_read("free mapping", (CORE_ADDR
)Ofree_mapping
,
1126 (char *) &free_mapping
, sizeof free_mapping
);
1127 Omap_table
= firstmap
;
1128 mapsize
= lastmap
- firstmap
;
1129 size
= mapsize
* sizeof(struct mapping
);
1130 tmp
= mach_malloc("mapping table", size
);
1131 mach_read("mapping table", (CORE_ADDR
)Omap_table
, tmp
, size
);
1132 map_table
= (struct mapping
*) tmp
;
1135 Ovlow
= (unsigned) Ovtop_table
;
1136 Ovhigh
= (unsigned) &Ovtop_table
[vtopsize
];
1137 Oplow
= (unsigned) Ophys_table
;
1138 Ophigh
= (unsigned) &Ophys_table
[physsize
];
1139 Omhead
= (unsigned) Ofree_mapping
;
1140 Omlow
= (unsigned) firstmap
;
1141 Omhigh
= (unsigned) lastmap
;
1142 mlow
= (unsigned) map_table
;
1143 mhigh
= (unsigned) &map_table
[mapsize
];
1144 mhead
= (unsigned) &free_mapping
;
1145 vlow
= (unsigned) vtop_table
;
1146 vhigh
= (unsigned) &vtop_table
[vtopsize
];
1147 plow
= (unsigned) phys_table
;
1148 phigh
= (unsigned) &phys_table
[physsize
];
1151 fprintf(stderr
, "Ovtop [%#x-%#x) Ophys [%#x-%#x) Omap %#x [%#x-%#x)\n",
1152 Ovlow
, Ovhigh
, Oplow
, Ophigh
, Omhead
, Omlow
, Omhigh
);
1153 fprintf(stderr
, "vtop [%#x-%#x) phys [%#x-%#x) map %#x [%#x-%#x)\n",
1154 vlow
, vhigh
, plow
, phigh
, mhead
, mlow
, mhigh
);
1156 return(adjustdata());
1169 } else if (IS_OVTOPPTR(ptr
)) {
1170 ret
= vlow
+ (ptr
- Ovlow
);
1172 } else if (IS_OPHYSPTR(ptr
)) {
1173 ret
= plow
+ (ptr
- Oplow
);
1175 } else if (IS_OMAPPTR(ptr
)) {
1176 ret
= mlow
+ (ptr
- Omlow
);
1178 } else if (ptr
== Omhead
) {
1182 error("bogus pointer %#x", ptr
);
1187 fprintf(stderr
, "%x (%s) -> %x\n", ptr
, str
, ret
);
1195 register int i
, lim
;
1197 struct phys_entry
*np
;
1202 for (nq
= vtop_table
; nq
< &vtop_table
[lim
]; nq
++) {
1203 nq
->next
= (queue_entry_t
) ptrcvt((unsigned)nq
->next
);
1204 nq
->prev
= (queue_entry_t
) ptrcvt((unsigned)nq
->prev
);
1209 for (np
= phys_table
; np
< &phys_table
[lim
]; np
++) {
1210 np
->phys_link
.next
= (queue_entry_t
)
1211 ptrcvt((unsigned)np
->phys_link
.next
);
1212 np
->phys_link
.prev
= (queue_entry_t
)
1213 ptrcvt((unsigned)np
->phys_link
.prev
);
1214 np
->writer
= (struct mapping
*) ptrcvt((unsigned)np
->writer
);
1218 free_mapping
.next
= (queue_entry_t
)ptrcvt((unsigned)free_mapping
.next
);
1219 free_mapping
.prev
= (queue_entry_t
)ptrcvt((unsigned)free_mapping
.prev
);
1221 for (nm
= map_table
; nm
< &map_table
[lim
]; nm
++) {
1222 nm
->hash_link
.next
= (queue_entry_t
)
1223 ptrcvt((unsigned)nm
->hash_link
.next
);
1224 nm
->hash_link
.prev
= (queue_entry_t
)
1225 ptrcvt((unsigned)nm
->hash_link
.prev
);
1226 nm
->phys_link
.next
= (queue_entry_t
)
1227 ptrcvt((unsigned)nm
->phys_link
.next
);
1228 nm
->phys_link
.prev
= (queue_entry_t
)
1229 ptrcvt((unsigned)nm
->phys_link
.prev
);
1235 * Consistency checks, make sure:
1237 * 1. all mappings are accounted for
1239 * 3. no wild pointers
1240 * 4. consisent TLB state
1245 register struct mapstate
*ms
;
1249 mapstate
= (struct mapstate
*)
1250 mach_malloc("map state", mapsize
* sizeof(struct mapstate
));
1251 for (ms
= mapstate
; ms
< &mapstate
[mapsize
]; ms
++) {
1253 ms
->hashix
= ms
->physix
= -2;
1257 * Check the free list
1259 checkhashchain(&free_mapping
, M_ISFREE
, -1);
1261 * Check every hash chain
1263 for (i
= 0; i
< vtopsize
; i
++)
1264 checkhashchain(&vtop_table
[i
], M_ISHASH
, i
);
1266 * Check every phys chain
1268 for (i
= 0; i
< physsize
; i
++)
1269 checkphyschain(&phys_table
[i
].phys_link
, M_ISPHYS
, i
);
1271 * Cycle through mapstate looking for anomolies
1274 for (i
= 0; i
< mapsize
; i
++) {
1275 switch (ms
->flags
) {
1277 case M_ISHASH
|M_ISPHYS
:
1280 merror(ms
, "not found");
1284 merror(ms
, "in vtop but not phys");
1288 merror(ms
, "in phys but not vtop");
1292 merror(ms
, "totally bogus");
1298 return(errors
? 0 : 1);
1302 checkhashchain(qhp
, flag
, ix
)
1305 register queue_entry_t qp
, pqp
;
1306 register struct mapping
*mp
;
1307 struct mapstate
*ms
;
1311 * First element is not a mapping structure,
1312 * chain must be empty.
1314 if (!IS_MAPPTR(qp
)) {
1315 if (qp
!= qhp
|| qp
!= qhp
->prev
)
1316 fatal("bad vtop_table header pointer");
1320 mp
= (struct mapping
*) qp
;
1321 qp
= &mp
->hash_link
;
1322 if (qp
->prev
!= pqp
)
1323 fatal("bad hash_link prev pointer");
1324 ms
= &mapstate
[mp
-map_table
];
1327 pqp
= (queue_entry_t
) mp
;
1329 } while (IS_MAPPTR(qp
));
1331 fatal("bad hash_link next pointer");
1336 checkphyschain(qhp
, flag
, ix
)
1339 register queue_entry_t qp
, pqp
;
1340 register struct mapping
*mp
;
1341 struct mapstate
*ms
;
1345 * First element is not a mapping structure,
1346 * chain must be empty.
1348 if (!IS_MAPPTR(qp
)) {
1349 if (qp
!= qhp
|| qp
!= qhp
->prev
)
1350 fatal("bad phys_table header pointer");
1354 mp
= (struct mapping
*) qp
;
1355 qp
= &mp
->phys_link
;
1356 if (qp
->prev
!= pqp
)
1357 fatal("bad phys_link prev pointer");
1358 ms
= &mapstate
[mp
-map_table
];
1361 pqp
= (queue_entry_t
) mp
;
1363 } while (IS_MAPPTR(qp
));
1365 fatal("bad phys_link next pointer");
1371 struct mapstate
*ms
;
1377 "vtophys: %s: %c%c%c, hashix %d, physix %d, mapping %x\n",
1379 (ms
->flags
& M_ISFREE
) ? 'F' : '-',
1380 (ms
->flags
& M_ISHASH
) ? 'H' : '-',
1381 (ms
->flags
& M_ISPHYS
) ? 'P' : '-',
1382 ms
->hashix
, ms
->physix
, &map_table
[ms
-mapstate
]);
1383 return_to_top_level();
1387 mach_read(str
, from
, top
, size
)
1396 from
= ksym_lookup(str
);
1397 paddr
= vtophys(0, from
);
1398 if (paddr
== ~0 || physrd(paddr
, top
, size
) != 0)
1399 fatal("cannot read %s", str
);
1403 mach_malloc(str
, size
)
1407 char *ptr
= (char *) malloc(size
);
1410 fatal("no memory for %s", str
);
1417 _initialize_hp9k8_dep()
1419 add_com ("process-address", class_obscure
, set_paddr_command
,
1420 "The process identified by (ps-style) ADDR becomes the\n\
1421 \"current\" process context for kernel debugging.");
1422 add_com_alias ("paddr", "process-address", class_obscure
, 0);
1423 add_com ("virtual-to-physical", class_obscure
, vtop_command
,
1424 "Translates the kernel virtual address ADDR into a physical address.");
1425 add_com_alias ("vtop", "virtual-to-physical", class_obscure
, 0);