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
)) {
561 /* Routines to extract various sized constants out of hppa
564 /* This assumes that no garbage lies outside of the lower bits of
568 sign_extend (val
, bits
)
571 return (int)(val
>> bits
- 1 ? (-1 << bits
) | val
: val
);
574 /* For many immediate values the sign bit is the low bit! */
577 low_sign_extend (val
, bits
)
580 return (int)((val
& 0x1 ? (-1 << (bits
- 1)) : 0) | val
>> 1);
582 /* extract the immediate field from a ld{bhw}s instruction */
587 get_field (val
, from
, to
)
588 unsigned val
, from
, to
;
590 val
= val
>> 31 - to
;
591 return val
& ((1 << 32 - from
) - 1);
595 set_field (val
, from
, to
, new_val
)
596 unsigned *val
, from
, to
;
598 unsigned mask
= ~((1 << (to
- from
+ 1)) << (31 - from
));
599 return *val
= *val
& mask
| (new_val
<< (31 - from
));
602 /* extract a 3-bit space register number from a be, ble, mtsp or mfsp */
607 return GET_FIELD (word
, 18, 18) << 2 | GET_FIELD (word
, 16, 17);
610 extract_5_load (word
)
613 return low_sign_extend (word
>> 16 & MASK_5
, 5);
616 /* extract the immediate field from a st{bhw}s instruction */
619 extract_5_store (word
)
622 return low_sign_extend (word
& MASK_5
, 5);
625 /* extract an 11 bit immediate field */
631 return low_sign_extend (word
& MASK_11
, 11);
634 /* extract a 14 bit immediate field */
640 return low_sign_extend (word
& MASK_14
, 14);
643 /* deposit a 14 bit constant in a word */
646 deposit_14 (opnd
, word
)
650 unsigned sign
= (opnd
< 0 ? 1 : 0);
652 return word
| ((unsigned)opnd
<< 1 & MASK_14
) | sign
;
655 /* extract a 21 bit constant */
665 val
= GET_FIELD (word
, 20, 20);
667 val
|= GET_FIELD (word
, 9, 19);
669 val
|= GET_FIELD (word
, 5, 6);
671 val
|= GET_FIELD (word
, 0, 4);
673 val
|= GET_FIELD (word
, 7, 8);
674 return sign_extend (val
, 21) << 11;
677 /* deposit a 21 bit constant in a word. Although 21 bit constants are
678 usually the top 21 bits of a 32 bit constant, we assume that only
679 the low 21 bits of opnd are relevant */
682 deposit_21 (opnd
, word
)
687 val
|= GET_FIELD (opnd
, 11 + 14, 11 + 18);
689 val
|= GET_FIELD (opnd
, 11 + 12, 11 + 13);
691 val
|= GET_FIELD (opnd
, 11 + 19, 11 + 20);
693 val
|= GET_FIELD (opnd
, 11 + 1, 11 + 11);
695 val
|= GET_FIELD (opnd
, 11 + 0, 11 + 0);
699 /* extract a 12 bit constant from branch instructions */
705 return sign_extend (GET_FIELD (word
, 19, 28) |
706 GET_FIELD (word
, 29, 29) << 10 |
707 (word
& 0x1) << 11, 12) << 2;
710 /* extract a 17 bit constant from branch instructions, returning the
711 19 bit signed value. */
717 return sign_extend (GET_FIELD (word
, 19, 28) |
718 GET_FIELD (word
, 29, 29) << 10 |
719 GET_FIELD (word
, 11, 15) << 11 |
720 (word
& 0x1) << 16, 17) << 2;
725 frame_saved_pc (frame
)
728 if (get_current_frame () == frame
)
730 struct frame_saved_regs saved_regs
;
732 get_frame_saved_regs (frame
, &saved_regs
);
733 if (saved_regs
.regs
[RP_REGNUM
])
734 return read_memory_integer (saved_regs
.regs
[RP_REGNUM
], 4);
736 return read_register (RP_REGNUM
);
738 return read_memory_integer (frame
->frame
- 20, 4) & ~0x3;
741 /* To see if a frame chain is valid, see if the caller looks like it
742 was compiled with gcc. */
744 int frame_chain_valid (chain
, thisframe
)
748 if (chain
&& (chain
> 0x60000000
749 /* || remote_debugging -this is no longer used */
755 CORE_ADDR pc
= get_pc_function_start (FRAME_SAVED_PC (thisframe
));
757 if (!inside_entry_file (pc
))
759 /* look for stw rp, -20(0,sp); copy 4,1; copy sp, 4 */
760 if (read_memory_integer (pc
, 4) == 0x6BC23FD9)
763 if (read_memory_integer (pc
, 4) == 0x8040241 &&
764 read_memory_integer (pc
+ 4, 4) == 0x81E0244)
773 /* Some helper functions. gcc_p returns 1 if the function beginning at
774 pc appears to have been compiled with gcc. hpux_cc_p returns 1 if
775 fn was compiled with hpux cc. gcc functions look like :
777 stw rp,-0x14(sp) ; optional
780 stwm r1,framesize(sp)
782 hpux cc functions look like:
784 stw rp,-0x14(sp) ; optional.
791 if (read_memory_integer (pc
, 4) == 0x6BC23FD9)
794 if (read_memory_integer (pc
, 4) == 0x8040241 &&
795 read_memory_integer (pc
+ 4, 4) == 0x81E0244)
801 find_dummy_frame_regs (frame
, frame_saved_regs
)
802 struct frame_info
*frame
;
803 struct frame_saved_regs
*frame_saved_regs
;
805 CORE_ADDR fp
= frame
->frame
;
808 frame_saved_regs
->regs
[RP_REGNUM
] = fp
- 20 & ~0x3;
809 frame_saved_regs
->regs
[FP_REGNUM
] = fp
;
810 frame_saved_regs
->regs
[1] = fp
+ 8;
811 frame_saved_regs
->regs
[3] = fp
+ 12;
812 for (fp
+= 16, i
= 3; i
< 30; fp
+= 4, i
++)
813 frame_saved_regs
->regs
[i
] = fp
;
814 frame_saved_regs
->regs
[31] = fp
;
816 for (i
= FP0_REGNUM
; i
< NUM_REGS
; i
++, fp
+= 8)
817 frame_saved_regs
->regs
[i
] = fp
;
818 /* depend on last increment of fp */
819 frame_saved_regs
->regs
[IPSW_REGNUM
] = fp
- 4;
820 frame_saved_regs
->regs
[SAR_REGNUM
] = fp
;
822 frame_saved_regs
->regs
[PCOQ_TAIL_REGNUM
] = fp
;
823 frame_saved_regs
->regs
[PCSQ_TAIL_REGNUM
] = fp
;
827 hp_push_arguments (nargs
, args
, sp
, struct_return
, struct_addr
)
832 CORE_ADDR struct_addr
;
834 /* array of arguments' offsets */
835 int *offset
= (int *)alloca(nargs
);
839 for (i
= 0; i
< nargs
; i
++)
841 cum
+= TYPE_LENGTH (VALUE_TYPE (args
[i
]));
842 /* value must go at proper alignment. Assume alignment is a
844 alignment
= hp_alignof (VALUE_TYPE (args
[i
]));
846 cum
= (cum
+ alignment
) & -alignment
;
849 for (i
== 0; i
< nargs
; i
++)
851 write_memory (sp
+ offset
[i
], VALUE_CONTENTS (args
[i
]), sizeof(int));
853 sp
+= min ((cum
+ 7) & -8, 48);
855 write_register (28, struct_addr
);
859 /* return the alignment of a type in bytes. Structures have the maximum
860 alignment required by their fields. */
866 int max_align
, align
, i
;
867 switch (TYPE_CODE (arg
))
872 return TYPE_LENGTH (arg
);
873 case TYPE_CODE_ARRAY
:
874 return hp_alignof (TYPE_FIELD_TYPE (arg
, 0));
875 case TYPE_CODE_STRUCT
:
876 case TYPE_CODE_UNION
:
878 for (i
= 0; i
< TYPE_NFIELDS (arg
); i
++)
880 /* Bit fields have no real alignment. */
881 if (!TYPE_FIELD_BITPOS (arg
, i
))
883 align
= hp_alignof (TYPE_FIELD_TYPE (arg
, i
));
884 max_align
= max (max_align
, align
);
893 /* Print the register regnum, or all registers if regnum is -1 */
895 pa_do_registers_info (regnum
, fpregs
)
899 char raw_regs
[REGISTER_BYTES
];
902 for (i
= 0; i
< NUM_REGS
; i
++)
903 read_relative_register_raw_bytes (i
, raw_regs
+ REGISTER_BYTE (i
));
905 pa_print_registers (raw_regs
, regnum
);
906 else if (regnum
< FP0_REGNUM
)
908 printf ("%s %x\n", reg_names
[regnum
], *(long *)(raw_regs
+
909 REGISTER_BYTE (regnum
)));
912 pa_print_fp_reg (regnum
);
915 pa_print_registers (raw_regs
, regnum
)
921 for (i
= 0; i
< 18; i
++)
922 printf ("%8.8s: %8x %8.8s: %8x %8.8s: %8x %8.8s: %8x\n",
924 *(int *)(raw_regs
+ REGISTER_BYTE (i
)),
926 *(int *)(raw_regs
+ REGISTER_BYTE (i
+ 18)),
928 *(int *)(raw_regs
+ REGISTER_BYTE (i
+ 36)),
930 *(int *)(raw_regs
+ REGISTER_BYTE (i
+ 54)));
931 for (i
= 72; i
< NUM_REGS
; i
++)
938 unsigned char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
939 unsigned char virtual_buffer
[MAX_REGISTER_VIRTUAL_SIZE
];
942 /* Get the data in raw format, then convert also to virtual format. */
943 read_relative_register_raw_bytes (i
, raw_buffer
);
944 REGISTER_CONVERT_TO_VIRTUAL (i
, raw_buffer
, virtual_buffer
);
946 fputs_filtered (reg_names
[i
], stdout
);
947 print_spaces_filtered (15 - strlen (reg_names
[i
]), stdout
);
949 val_print (REGISTER_VIRTUAL_TYPE (i
), virtual_buffer
, 0, stdout
, 0,
950 1, 0, Val_pretty_default
);
951 printf_filtered ("\n");
956 * Virtual to physical translation routines for Utah's Mach 3.0
958 #ifdef MACHKERNELDEBUG
962 #if 0 /* too many includes to resolve, too much crap */
963 #include <kern/queue.h>
965 #include <mach/vm_prot.h>
969 struct queue_entry
*next
; /* next element */
970 struct queue_entry
*prev
; /* previous element */
973 typedef struct queue_entry
*queue_t
;
974 typedef struct queue_entry queue_head_t
;
975 typedef struct queue_entry queue_chain_t
;
976 typedef struct queue_entry
*queue_entry_t
;
979 #define HP800_HASHSIZE 1024
980 #define HP800_HASHSIZE_LOG2 10
982 #define pmap_hash(space, offset) \
983 (((unsigned) (space) << 5 ^ \
984 ((unsigned) (offset) >> 19 | (unsigned) (space) << 13) ^ \
985 (unsigned) (offset) >> 11) & (HP800_HASHSIZE-1))
988 queue_head_t hash_link
; /* hash table links */
989 queue_head_t phys_link
; /* for mappings of a given PA */
990 space_t space
; /* virtual space */
991 unsigned offset
; /* virtual page number */
992 unsigned tlbpage
; /* physical page (for TLB load) */
993 unsigned tlbprot
; /* prot/access rights (for TLB load) */
994 struct pmap
*pmap
; /* pmap mapping belongs to */
998 queue_head_t phys_link
; /* head of mappings of a given PA */
999 struct mapping
*writer
; /* mapping with R/W access */
1000 unsigned tlbprot
; /* TLB format protection */
1005 #define atop(a) ((unsigned)(a) >> 11)
1006 #define ptoa(p) ((unsigned)(p) << 11)
1007 #define trunc_page(a) ((unsigned)(a) & ~2047)
1009 STATIC
long equiv_end
;
1010 STATIC queue_head_t
*Ovtop_table
, *vtop_table
, *Ofree_mapping
, free_mapping
;
1011 STATIC
struct phys_entry
*Ophys_table
, *phys_table
;
1012 STATIC
long vm_last_phys
, vm_first_phys
;
1013 STATIC
struct mapping
*firstmap
, *lastmap
, *Omap_table
, *map_table
;
1014 STATIC
unsigned Omlow
, Omhigh
, Omhead
, Ovlow
, Ovhigh
, Oplow
, Ophigh
;
1015 STATIC
unsigned mlow
, mhigh
, mhead
, vlow
, vhigh
, plow
, phigh
;
1016 STATIC
int vtopsize
, physsize
, mapsize
;
1019 #define IS_OVTOPPTR(p) ((unsigned)(p) >= Ovlow && (unsigned)(p) < Ovhigh)
1020 #define IS_OMAPPTR(p) ((unsigned)(p) >= Omlow && (unsigned)(p) < Omhigh)
1021 #define IS_OPHYSPTR(p) ((unsigned)(p) >= Oplow && (unsigned)(p) < Ophigh)
1022 #define IS_VTOPPTR(p) ((unsigned)(p) >= vlow && (unsigned)(p) < vhigh)
1023 #define IS_MAPPTR(p) ((unsigned)(p) >= mlow && (unsigned)(p) < mhigh)
1024 #define IS_PHYSPTR(p) ((unsigned)(p) >= plow && (unsigned)(p) < phigh)
1050 "translate: may not be able to translate all addresses\n");
1054 mach_vtophys(space
, off
, pa
)
1055 unsigned space
, off
, *pa
;
1058 register queue_t qp
;
1059 register struct mapping
*mp
;
1063 * Kernel IO or equivilently mapped, one to one.
1065 if (space
== 0 && (long)off
< equiv_end
) {
1070 * Else look it up in specified space
1072 poff
= off
- trunc_page(off
);
1073 off
= trunc_page(off
);
1074 qp
= &vtop_table
[pmap_hash(space
, off
)];
1075 for (mp
= (struct mapping
*)qp
->next
;
1076 qp
!= (queue_entry_t
)mp
;
1077 mp
= (struct mapping
*)mp
->hash_link
.next
) {
1078 if (mp
->space
== space
&& mp
->offset
== off
) {
1079 *pa
= (mp
->tlbpage
<< 7) | poff
;
1089 char *tmp
, *mach_malloc();
1093 mach_read("equiv_end", ~0, (char *)&equiv_end
, sizeof equiv_end
);
1094 mach_read("vm_first_phys", ~0,
1095 (char *)&vm_first_phys
, sizeof vm_first_phys
);
1096 mach_read("vm_last_phys", ~0,
1097 (char *)&vm_last_phys
, sizeof vm_last_phys
);
1098 mach_read("firstmap", ~0, (char *)&firstmap
, sizeof firstmap
);
1099 mach_read("lastmap", ~0, (char *)&lastmap
, sizeof lastmap
);
1101 /* virtual to physical hash table */
1102 vtopsize
= HP800_HASHSIZE
;
1103 size
= vtopsize
* sizeof(queue_head_t
);
1104 tmp
= mach_malloc("vtop table", size
);
1105 mach_read("vtop_table", ~0, (char *)&Ovtop_table
, sizeof Ovtop_table
);
1106 mach_read("vtop table", (CORE_ADDR
)Ovtop_table
, tmp
, size
);
1107 vtop_table
= (queue_head_t
*) tmp
;
1109 /* inverted page table */
1110 physsize
= atop(vm_last_phys
- vm_first_phys
);
1111 size
= physsize
* sizeof(struct phys_entry
);
1112 tmp
= mach_malloc("phys table", size
);
1113 mach_read("phys_table", ~0, (char *)&Ophys_table
, sizeof Ophys_table
);
1114 mach_read("phys table", (CORE_ADDR
)Ophys_table
, tmp
, size
);
1115 phys_table
= (struct phys_entry
*) tmp
;
1117 /* mapping structures */
1118 Ofree_mapping
= (queue_head_t
*) ksym_lookup("free_mapping");
1119 mach_read("free mapping", (CORE_ADDR
)Ofree_mapping
,
1120 (char *) &free_mapping
, sizeof free_mapping
);
1121 Omap_table
= firstmap
;
1122 mapsize
= lastmap
- firstmap
;
1123 size
= mapsize
* sizeof(struct mapping
);
1124 tmp
= mach_malloc("mapping table", size
);
1125 mach_read("mapping table", (CORE_ADDR
)Omap_table
, tmp
, size
);
1126 map_table
= (struct mapping
*) tmp
;
1129 Ovlow
= (unsigned) Ovtop_table
;
1130 Ovhigh
= (unsigned) &Ovtop_table
[vtopsize
];
1131 Oplow
= (unsigned) Ophys_table
;
1132 Ophigh
= (unsigned) &Ophys_table
[physsize
];
1133 Omhead
= (unsigned) Ofree_mapping
;
1134 Omlow
= (unsigned) firstmap
;
1135 Omhigh
= (unsigned) lastmap
;
1136 mlow
= (unsigned) map_table
;
1137 mhigh
= (unsigned) &map_table
[mapsize
];
1138 mhead
= (unsigned) &free_mapping
;
1139 vlow
= (unsigned) vtop_table
;
1140 vhigh
= (unsigned) &vtop_table
[vtopsize
];
1141 plow
= (unsigned) phys_table
;
1142 phigh
= (unsigned) &phys_table
[physsize
];
1145 fprintf(stderr
, "Ovtop [%#x-%#x) Ophys [%#x-%#x) Omap %#x [%#x-%#x)\n",
1146 Ovlow
, Ovhigh
, Oplow
, Ophigh
, Omhead
, Omlow
, Omhigh
);
1147 fprintf(stderr
, "vtop [%#x-%#x) phys [%#x-%#x) map %#x [%#x-%#x)\n",
1148 vlow
, vhigh
, plow
, phigh
, mhead
, mlow
, mhigh
);
1150 return(adjustdata());
1163 } else if (IS_OVTOPPTR(ptr
)) {
1164 ret
= vlow
+ (ptr
- Ovlow
);
1166 } else if (IS_OPHYSPTR(ptr
)) {
1167 ret
= plow
+ (ptr
- Oplow
);
1169 } else if (IS_OMAPPTR(ptr
)) {
1170 ret
= mlow
+ (ptr
- Omlow
);
1172 } else if (ptr
== Omhead
) {
1176 error("bogus pointer %#x", ptr
);
1181 fprintf(stderr
, "%x (%s) -> %x\n", ptr
, str
, ret
);
1189 register int i
, lim
;
1191 struct phys_entry
*np
;
1196 for (nq
= vtop_table
; nq
< &vtop_table
[lim
]; nq
++) {
1197 nq
->next
= (queue_entry_t
) ptrcvt((unsigned)nq
->next
);
1198 nq
->prev
= (queue_entry_t
) ptrcvt((unsigned)nq
->prev
);
1203 for (np
= phys_table
; np
< &phys_table
[lim
]; np
++) {
1204 np
->phys_link
.next
= (queue_entry_t
)
1205 ptrcvt((unsigned)np
->phys_link
.next
);
1206 np
->phys_link
.prev
= (queue_entry_t
)
1207 ptrcvt((unsigned)np
->phys_link
.prev
);
1208 np
->writer
= (struct mapping
*) ptrcvt((unsigned)np
->writer
);
1212 free_mapping
.next
= (queue_entry_t
)ptrcvt((unsigned)free_mapping
.next
);
1213 free_mapping
.prev
= (queue_entry_t
)ptrcvt((unsigned)free_mapping
.prev
);
1215 for (nm
= map_table
; nm
< &map_table
[lim
]; nm
++) {
1216 nm
->hash_link
.next
= (queue_entry_t
)
1217 ptrcvt((unsigned)nm
->hash_link
.next
);
1218 nm
->hash_link
.prev
= (queue_entry_t
)
1219 ptrcvt((unsigned)nm
->hash_link
.prev
);
1220 nm
->phys_link
.next
= (queue_entry_t
)
1221 ptrcvt((unsigned)nm
->phys_link
.next
);
1222 nm
->phys_link
.prev
= (queue_entry_t
)
1223 ptrcvt((unsigned)nm
->phys_link
.prev
);
1229 * Consistency checks, make sure:
1231 * 1. all mappings are accounted for
1233 * 3. no wild pointers
1234 * 4. consisent TLB state
1239 register struct mapstate
*ms
;
1243 mapstate
= (struct mapstate
*)
1244 mach_malloc("map state", mapsize
* sizeof(struct mapstate
));
1245 for (ms
= mapstate
; ms
< &mapstate
[mapsize
]; ms
++) {
1247 ms
->hashix
= ms
->physix
= -2;
1251 * Check the free list
1253 checkhashchain(&free_mapping
, M_ISFREE
, -1);
1255 * Check every hash chain
1257 for (i
= 0; i
< vtopsize
; i
++)
1258 checkhashchain(&vtop_table
[i
], M_ISHASH
, i
);
1260 * Check every phys chain
1262 for (i
= 0; i
< physsize
; i
++)
1263 checkphyschain(&phys_table
[i
].phys_link
, M_ISPHYS
, i
);
1265 * Cycle through mapstate looking for anomolies
1268 for (i
= 0; i
< mapsize
; i
++) {
1269 switch (ms
->flags
) {
1271 case M_ISHASH
|M_ISPHYS
:
1274 merror(ms
, "not found");
1278 merror(ms
, "in vtop but not phys");
1282 merror(ms
, "in phys but not vtop");
1286 merror(ms
, "totally bogus");
1292 return(errors
? 0 : 1);
1296 checkhashchain(qhp
, flag
, ix
)
1299 register queue_entry_t qp
, pqp
;
1300 register struct mapping
*mp
;
1301 struct mapstate
*ms
;
1305 * First element is not a mapping structure,
1306 * chain must be empty.
1308 if (!IS_MAPPTR(qp
)) {
1309 if (qp
!= qhp
|| qp
!= qhp
->prev
)
1310 fatal("bad vtop_table header pointer");
1314 mp
= (struct mapping
*) qp
;
1315 qp
= &mp
->hash_link
;
1316 if (qp
->prev
!= pqp
)
1317 fatal("bad hash_link prev pointer");
1318 ms
= &mapstate
[mp
-map_table
];
1321 pqp
= (queue_entry_t
) mp
;
1323 } while (IS_MAPPTR(qp
));
1325 fatal("bad hash_link next pointer");
1330 checkphyschain(qhp
, flag
, ix
)
1333 register queue_entry_t qp
, pqp
;
1334 register struct mapping
*mp
;
1335 struct mapstate
*ms
;
1339 * First element is not a mapping structure,
1340 * chain must be empty.
1342 if (!IS_MAPPTR(qp
)) {
1343 if (qp
!= qhp
|| qp
!= qhp
->prev
)
1344 fatal("bad phys_table header pointer");
1348 mp
= (struct mapping
*) qp
;
1349 qp
= &mp
->phys_link
;
1350 if (qp
->prev
!= pqp
)
1351 fatal("bad phys_link prev pointer");
1352 ms
= &mapstate
[mp
-map_table
];
1355 pqp
= (queue_entry_t
) mp
;
1357 } while (IS_MAPPTR(qp
));
1359 fatal("bad phys_link next pointer");
1365 struct mapstate
*ms
;
1371 "vtophys: %s: %c%c%c, hashix %d, physix %d, mapping %x\n",
1373 (ms
->flags
& M_ISFREE
) ? 'F' : '-',
1374 (ms
->flags
& M_ISHASH
) ? 'H' : '-',
1375 (ms
->flags
& M_ISPHYS
) ? 'P' : '-',
1376 ms
->hashix
, ms
->physix
, &map_table
[ms
-mapstate
]);
1377 return_to_top_level();
1381 mach_read(str
, from
, top
, size
)
1390 from
= ksym_lookup(str
);
1391 paddr
= vtophys(0, from
);
1392 if (paddr
== ~0 || physrd(paddr
, top
, size
) != 0)
1393 fatal("cannot read %s", str
);
1397 mach_malloc(str
, size
)
1401 char *ptr
= (char *) malloc(size
);
1404 fatal("no memory for %s", str
);
1411 _initialize_hp9k8_dep()
1413 add_com ("process-address", class_obscure
, set_paddr_command
,
1414 "The process identified by (ps-style) ADDR becomes the\n\
1415 \"current\" process context for kernel debugging.");
1416 add_com_alias ("paddr", "process-address", class_obscure
, 0);
1417 add_com ("virtual-to-physical", class_obscure
, vtop_command
,
1418 "Translates the kernel virtual address ADDR into a physical address.");
1419 add_com_alias ("vtop", "virtual-to-physical", class_obscure
, 0);