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)) {
562 /* Routines to extract various sized constants out of hppa
565 /* This assumes that no garbage lies outside of the lower bits of
569 sign_extend (val, bits)
572 return (int)(val >> bits - 1 ? (-1 << bits) | val : val);
575 /* For many immediate values the sign bit is the low bit! */
578 low_sign_extend (val, bits)
581 return (int)((val & 0x1 ? (-1 << (bits - 1)) : 0) | val >> 1);
583 /* extract the immediate field from a ld{bhw}s instruction */
588 get_field (val, from, to)
589 unsigned val, from, to;
591 val = val >> 31 - to;
592 return val & ((1 << 32 - from) - 1);
596 set_field (val, from, to, new_val)
597 unsigned *val, from, to;
599 unsigned mask = ~((1 << (to - from + 1)) << (31 - from));
600 return *val = *val & mask | (new_val << (31 - from));
603 /* extract a 3-bit space register number from a be, ble, mtsp or mfsp */
608 return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);
611 extract_5_load (word)
614 return low_sign_extend (word >> 16 & MASK_5, 5);
617 /* extract the immediate field from a st{bhw}s instruction */
620 extract_5_store (word)
623 return low_sign_extend (word & MASK_5, 5);
626 /* extract an 11 bit immediate field */
632 return low_sign_extend (word & MASK_11, 11);
635 /* extract a 14 bit immediate field */
641 return low_sign_extend (word & MASK_14, 14);
644 /* deposit a 14 bit constant in a word */
647 deposit_14 (opnd, word)
651 unsigned sign = (opnd < 0 ? 1 : 0);
653 return word | ((unsigned)opnd << 1 & MASK_14) | sign;
656 /* extract a 21 bit constant */
666 val = GET_FIELD (word, 20, 20);
668 val |= GET_FIELD (word, 9, 19);
670 val |= GET_FIELD (word, 5, 6);
672 val |= GET_FIELD (word, 0, 4);
674 val |= GET_FIELD (word, 7, 8);
675 return sign_extend (val, 21) << 11;
678 /* deposit a 21 bit constant in a word. Although 21 bit constants are
679 usually the top 21 bits of a 32 bit constant, we assume that only
680 the low 21 bits of opnd are relevant */
683 deposit_21 (opnd, word)
688 val |= GET_FIELD (opnd, 11 + 14, 11 + 18);
690 val |= GET_FIELD (opnd, 11 + 12, 11 + 13);
692 val |= GET_FIELD (opnd, 11 + 19, 11 + 20);
694 val |= GET_FIELD (opnd, 11 + 1, 11 + 11);
696 val |= GET_FIELD (opnd, 11 + 0, 11 + 0);
700 /* extract a 12 bit constant from branch instructions */
706 return sign_extend (GET_FIELD (word, 19, 28) |
707 GET_FIELD (word, 29, 29) << 10 |
708 (word & 0x1) << 11, 12) << 2;
711 /* extract a 17 bit constant from branch instructions, returning the
712 19 bit signed value. */
718 return sign_extend (GET_FIELD (word, 19, 28) |
719 GET_FIELD (word, 29, 29) << 10 |
720 GET_FIELD (word, 11, 15) << 11 |
721 (word & 0x1) << 16, 17) << 2;
726 frame_saved_pc (frame)
729 if (get_current_frame () == frame)
731 struct frame_saved_regs saved_regs;
733 get_frame_saved_regs (frame, &saved_regs);
734 if (saved_regs.regs[RP_REGNUM])
735 return read_memory_integer (saved_regs.regs[RP_REGNUM], 4);
737 return read_register (RP_REGNUM);
739 return read_memory_integer (frame->frame - 20, 4) & ~0x3;
742 /* To see if a frame chain is valid, see if the caller looks like it
743 was compiled with gcc. */
745 int frame_chain_valid (chain, thisframe)
749 if (chain && (chain > 0x60000000
750 /* || remote_debugging -this is no longer used */
756 CORE_ADDR pc = get_pc_function_start (FRAME_SAVED_PC (thisframe));
758 if (!inside_entry_file (pc))
760 /* look for stw rp, -20(0,sp); copy 4,1; copy sp, 4 */
761 if (read_memory_integer (pc, 4) == 0x6BC23FD9)
764 if (read_memory_integer (pc, 4) == 0x8040241 &&
765 read_memory_integer (pc + 4, 4) == 0x81E0244)
774 /* Some helper functions. gcc_p returns 1 if the function beginning at
775 pc appears to have been compiled with gcc. hpux_cc_p returns 1 if
776 fn was compiled with hpux cc. gcc functions look like :
778 stw rp,-0x14(sp) ; optional
781 stwm r1,framesize(sp)
783 hpux cc functions look like:
785 stw rp,-0x14(sp) ; optional.
792 if (read_memory_integer (pc, 4) == 0x6BC23FD9)
795 if (read_memory_integer (pc, 4) == 0x8040241 &&
796 read_memory_integer (pc + 4, 4) == 0x81E0244)
802 find_dummy_frame_regs (frame, frame_saved_regs)
803 struct frame_info *frame;
804 struct frame_saved_regs *frame_saved_regs;
806 CORE_ADDR fp = frame->frame;
809 frame_saved_regs->regs[RP_REGNUM] = fp - 20 & ~0x3;
810 frame_saved_regs->regs[FP_REGNUM] = fp;
811 frame_saved_regs->regs[1] = fp + 8;
812 frame_saved_regs->regs[3] = fp + 12;
813 for (fp += 16, i = 3; i < 30; fp += 4, i++)
814 frame_saved_regs->regs[i] = fp;
815 frame_saved_regs->regs[31] = fp;
817 for (i = FP0_REGNUM; i < NUM_REGS; i++, fp += 8)
818 frame_saved_regs->regs[i] = fp;
819 /* depend on last increment of fp */
820 frame_saved_regs->regs[IPSW_REGNUM] = fp - 4;
821 frame_saved_regs->regs[SAR_REGNUM] = fp;
823 frame_saved_regs->regs[PCOQ_TAIL_REGNUM] = fp;
824 frame_saved_regs->regs[PCSQ_TAIL_REGNUM] = fp;
828 hp_push_arguments (nargs, args, sp, struct_return, struct_addr)
833 CORE_ADDR struct_addr;
835 /* array of arguments' offsets */
836 int *offset = (int *)alloca(nargs);
840 for (i = 0; i < nargs; i++)
842 cum += TYPE_LENGTH (VALUE_TYPE (args[i]));
843 /* value must go at proper alignment. Assume alignment is a
845 alignment = hp_alignof (VALUE_TYPE (args[i]));
847 cum = (cum + alignment) & -alignment;
850 for (i == 0; i < nargs; i++)
852 write_memory (sp + offset[i], VALUE_CONTENTS (args[i]), sizeof(int));
854 sp += min ((cum + 7) & -8, 48);
856 write_register (28, struct_addr);
860 /* return the alignment of a type in bytes. Structures have the maximum
861 alignment required by their fields. */
867 int max_align, align, i;
868 switch (TYPE_CODE (arg))
873 return TYPE_LENGTH (arg);
874 case TYPE_CODE_ARRAY:
875 return hp_alignof (TYPE_FIELD_TYPE (arg, 0));
876 case TYPE_CODE_STRUCT:
877 case TYPE_CODE_UNION:
879 for (i = 0; i < TYPE_NFIELDS (arg); i++)
881 /* Bit fields have no real alignment. */
882 if (!TYPE_FIELD_BITPOS (arg, i))
884 align = hp_alignof (TYPE_FIELD_TYPE (arg, i));
885 max_align = max (max_align, align);
894 /* Print the register regnum, or all registers if regnum is -1 */
896 pa_do_registers_info (regnum, fpregs)
900 char raw_regs [REGISTER_BYTES];
903 for (i = 0; i < NUM_REGS; i++)
904 read_relative_register_raw_bytes (i, raw_regs + REGISTER_BYTE (i));
906 pa_print_registers (raw_regs, regnum);
907 else if (regnum < FP0_REGNUM)
909 printf ("%s %x\n", reg_names[regnum], *(long *)(raw_regs +
910 REGISTER_BYTE (regnum)));
913 pa_print_fp_reg (regnum);
916 pa_print_registers (raw_regs, regnum)
922 for (i = 0; i < 18; i++)
923 printf ("%8.8s: %8x %8.8s: %8x %8.8s: %8x %8.8s: %8x\n",
925 *(int *)(raw_regs + REGISTER_BYTE (i)),
927 *(int *)(raw_regs + REGISTER_BYTE (i + 18)),
929 *(int *)(raw_regs + REGISTER_BYTE (i + 36)),
931 *(int *)(raw_regs + REGISTER_BYTE (i + 54)));
932 for (i = 72; i < NUM_REGS; i++)
939 unsigned char raw_buffer[MAX_REGISTER_RAW_SIZE];
940 unsigned char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
943 /* Get the data in raw format, then convert also to virtual format. */
944 read_relative_register_raw_bytes (i, raw_buffer);
945 REGISTER_CONVERT_TO_VIRTUAL (i, raw_buffer, virtual_buffer);
947 fputs_filtered (reg_names[i], stdout);
948 print_spaces_filtered (15 - strlen (reg_names[i]), stdout);
950 val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, stdout, 0,
951 1, 0, Val_pretty_default);
952 printf_filtered ("\n");
957 * Virtual to physical translation routines for Utah's Mach 3.0
959 #ifdef MACHKERNELDEBUG
963 #if 0 /* too many includes to resolve, too much crap */
964 #include <kern/queue.h>
966 #include <mach/vm_prot.h>
970 struct queue_entry *next; /* next element */
971 struct queue_entry *prev; /* previous element */
974 typedef struct queue_entry *queue_t;
975 typedef struct queue_entry queue_head_t;
976 typedef struct queue_entry queue_chain_t;
977 typedef struct queue_entry *queue_entry_t;
980 #define HP800_HASHSIZE 1024
981 #define HP800_HASHSIZE_LOG2 10
983 #define pmap_hash(space, offset) \
984 (((unsigned) (space) << 5 ^ \
985 ((unsigned) (offset) >> 19 | (unsigned) (space) << 13) ^ \
986 (unsigned) (offset) >> 11) & (HP800_HASHSIZE-1))
989 queue_head_t hash_link; /* hash table links */
990 queue_head_t phys_link; /* for mappings of a given PA */
991 space_t space; /* virtual space */
992 unsigned offset; /* virtual page number */
993 unsigned tlbpage; /* physical page (for TLB load) */
994 unsigned tlbprot; /* prot/access rights (for TLB load) */
995 struct pmap *pmap; /* pmap mapping belongs to */
999 queue_head_t phys_link; /* head of mappings of a given PA */
1000 struct mapping *writer; /* mapping with R/W access */
1001 unsigned tlbprot; /* TLB format protection */
1006 #define atop(a) ((unsigned)(a) >> 11)
1007 #define ptoa(p) ((unsigned)(p) << 11)
1008 #define trunc_page(a) ((unsigned)(a) & ~2047)
1010 STATIC long equiv_end;
1011 STATIC queue_head_t *Ovtop_table, *vtop_table, *Ofree_mapping, free_mapping;
1012 STATIC struct phys_entry *Ophys_table, *phys_table;
1013 STATIC long vm_last_phys, vm_first_phys;
1014 STATIC struct mapping *firstmap, *lastmap, *Omap_table, *map_table;
1015 STATIC unsigned Omlow, Omhigh, Omhead, Ovlow, Ovhigh, Oplow, Ophigh;
1016 STATIC unsigned mlow, mhigh, mhead, vlow, vhigh, plow, phigh;
1017 STATIC int vtopsize, physsize, mapsize;
1020 #define IS_OVTOPPTR(p) ((unsigned)(p) >= Ovlow && (unsigned)(p) < Ovhigh)
1021 #define IS_OMAPPTR(p) ((unsigned)(p) >= Omlow && (unsigned)(p) < Omhigh)
1022 #define IS_OPHYSPTR(p) ((unsigned)(p) >= Oplow && (unsigned)(p) < Ophigh)
1023 #define IS_VTOPPTR(p) ((unsigned)(p) >= vlow && (unsigned)(p) < vhigh)
1024 #define IS_MAPPTR(p) ((unsigned)(p) >= mlow && (unsigned)(p) < mhigh)
1025 #define IS_PHYSPTR(p) ((unsigned)(p) >= plow && (unsigned)(p) < phigh)
1051 "translate: may not be able to translate all addresses\n");
1055 mach_vtophys(space, off, pa)
1056 unsigned space, off, *pa;
1059 register queue_t qp;
1060 register struct mapping *mp;
1064 * Kernel IO or equivilently mapped, one to one.
1066 if (space == 0 && (long)off < equiv_end) {
1071 * Else look it up in specified space
1073 poff = off - trunc_page(off);
1074 off = trunc_page(off);
1075 qp = &vtop_table[pmap_hash(space, off)];
1076 for (mp = (struct mapping *)qp->next;
1077 qp != (queue_entry_t)mp;
1078 mp = (struct mapping *)mp->hash_link.next) {
1079 if (mp->space == space && mp->offset == off) {
1080 *pa = (mp->tlbpage << 7) | poff;
1090 char *tmp, *mach_malloc();
1094 mach_read("equiv_end", ~0, (char *)&equiv_end, sizeof equiv_end);
1095 mach_read("vm_first_phys", ~0,
1096 (char *)&vm_first_phys, sizeof vm_first_phys);
1097 mach_read("vm_last_phys", ~0,
1098 (char *)&vm_last_phys, sizeof vm_last_phys);
1099 mach_read("firstmap", ~0, (char *)&firstmap, sizeof firstmap);
1100 mach_read("lastmap", ~0, (char *)&lastmap, sizeof lastmap);
1102 /* virtual to physical hash table */
1103 vtopsize = HP800_HASHSIZE;
1104 size = vtopsize * sizeof(queue_head_t);
1105 tmp = mach_malloc("vtop table", size);
1106 mach_read("vtop_table", ~0, (char *)&Ovtop_table, sizeof Ovtop_table);
1107 mach_read("vtop table", (CORE_ADDR)Ovtop_table, tmp, size);
1108 vtop_table = (queue_head_t *) tmp;
1110 /* inverted page table */
1111 physsize = atop(vm_last_phys - vm_first_phys);
1112 size = physsize * sizeof(struct phys_entry);
1113 tmp = mach_malloc("phys table", size);
1114 mach_read("phys_table", ~0, (char *)&Ophys_table, sizeof Ophys_table);
1115 mach_read("phys table", (CORE_ADDR)Ophys_table, tmp, size);
1116 phys_table = (struct phys_entry *) tmp;
1118 /* mapping structures */
1119 Ofree_mapping = (queue_head_t *) ksym_lookup("free_mapping");
1120 mach_read("free mapping", (CORE_ADDR)Ofree_mapping,
1121 (char *) &free_mapping, sizeof free_mapping);
1122 Omap_table = firstmap;
1123 mapsize = lastmap - firstmap;
1124 size = mapsize * sizeof(struct mapping);
1125 tmp = mach_malloc("mapping table", size);
1126 mach_read("mapping table", (CORE_ADDR)Omap_table, tmp, size);
1127 map_table = (struct mapping *) tmp;
1130 Ovlow = (unsigned) Ovtop_table;
1131 Ovhigh = (unsigned) &Ovtop_table[vtopsize];
1132 Oplow = (unsigned) Ophys_table;
1133 Ophigh = (unsigned) &Ophys_table[physsize];
1134 Omhead = (unsigned) Ofree_mapping;
1135 Omlow = (unsigned) firstmap;
1136 Omhigh = (unsigned) lastmap;
1137 mlow = (unsigned) map_table;
1138 mhigh = (unsigned) &map_table[mapsize];
1139 mhead = (unsigned) &free_mapping;
1140 vlow = (unsigned) vtop_table;
1141 vhigh = (unsigned) &vtop_table[vtopsize];
1142 plow = (unsigned) phys_table;
1143 phigh = (unsigned) &phys_table[physsize];
1146 fprintf(stderr, "Ovtop [%#x-%#x) Ophys [%#x-%#x) Omap %#x [%#x-%#x)\n",
1147 Ovlow, Ovhigh, Oplow, Ophigh, Omhead, Omlow, Omhigh);
1148 fprintf(stderr, "vtop [%#x-%#x) phys [%#x-%#x) map %#x [%#x-%#x)\n",
1149 vlow, vhigh, plow, phigh, mhead, mlow, mhigh);
1151 return(adjustdata());
1164 } else if (IS_OVTOPPTR(ptr)) {
1165 ret = vlow + (ptr - Ovlow);
1167 } else if (IS_OPHYSPTR(ptr)) {
1168 ret = plow + (ptr - Oplow);
1170 } else if (IS_OMAPPTR(ptr)) {
1171 ret = mlow + (ptr - Omlow);
1173 } else if (ptr == Omhead) {
1177 error("bogus pointer %#x", ptr);
1182 fprintf(stderr, "%x (%s) -> %x\n", ptr, str, ret);
1190 register int i, lim;
1192 struct phys_entry *np;
1197 for (nq = vtop_table; nq < &vtop_table[lim]; nq++) {
1198 nq->next = (queue_entry_t) ptrcvt((unsigned)nq->next);
1199 nq->prev = (queue_entry_t) ptrcvt((unsigned)nq->prev);
1204 for (np = phys_table; np < &phys_table[lim]; np++) {
1205 np->phys_link.next = (queue_entry_t)
1206 ptrcvt((unsigned)np->phys_link.next);
1207 np->phys_link.prev = (queue_entry_t)
1208 ptrcvt((unsigned)np->phys_link.prev);
1209 np->writer = (struct mapping *) ptrcvt((unsigned)np->writer);
1213 free_mapping.next = (queue_entry_t)ptrcvt((unsigned)free_mapping.next);
1214 free_mapping.prev = (queue_entry_t)ptrcvt((unsigned)free_mapping.prev);
1216 for (nm = map_table; nm < &map_table[lim]; nm++) {
1217 nm->hash_link.next = (queue_entry_t)
1218 ptrcvt((unsigned)nm->hash_link.next);
1219 nm->hash_link.prev = (queue_entry_t)
1220 ptrcvt((unsigned)nm->hash_link.prev);
1221 nm->phys_link.next = (queue_entry_t)
1222 ptrcvt((unsigned)nm->phys_link.next);
1223 nm->phys_link.prev = (queue_entry_t)
1224 ptrcvt((unsigned)nm->phys_link.prev);
1230 * Consistency checks, make sure:
1232 * 1. all mappings are accounted for
1234 * 3. no wild pointers
1235 * 4. consisent TLB state
1240 register struct mapstate *ms;
1244 mapstate = (struct mapstate *)
1245 mach_malloc("map state", mapsize * sizeof(struct mapstate));
1246 for (ms = mapstate; ms < &mapstate[mapsize]; ms++) {
1248 ms->hashix = ms->physix = -2;
1252 * Check the free list
1254 checkhashchain(&free_mapping, M_ISFREE, -1);
1256 * Check every hash chain
1258 for (i = 0; i < vtopsize; i++)
1259 checkhashchain(&vtop_table[i], M_ISHASH, i);
1261 * Check every phys chain
1263 for (i = 0; i < physsize; i++)
1264 checkphyschain(&phys_table[i].phys_link, M_ISPHYS, i);
1266 * Cycle through mapstate looking for anomolies
1269 for (i = 0; i < mapsize; i++) {
1270 switch (ms->flags) {
1272 case M_ISHASH|M_ISPHYS:
1275 merror(ms, "not found");
1279 merror(ms, "in vtop but not phys");
1283 merror(ms, "in phys but not vtop");
1287 merror(ms, "totally bogus");
1293 return(errors ? 0 : 1);
1297 checkhashchain(qhp, flag, ix)
1300 register queue_entry_t qp, pqp;
1301 register struct mapping *mp;
1302 struct mapstate *ms;
1306 * First element is not a mapping structure,
1307 * chain must be empty.
1309 if (!IS_MAPPTR(qp)) {
1310 if (qp != qhp || qp != qhp->prev)
1311 fatal("bad vtop_table header pointer");
1315 mp = (struct mapping *) qp;
1316 qp = &mp->hash_link;
1317 if (qp->prev != pqp)
1318 fatal("bad hash_link prev pointer");
1319 ms = &mapstate[mp-map_table];
1322 pqp = (queue_entry_t) mp;
1324 } while (IS_MAPPTR(qp));
1326 fatal("bad hash_link next pointer");
1331 checkphyschain(qhp, flag, ix)
1334 register queue_entry_t qp, pqp;
1335 register struct mapping *mp;
1336 struct mapstate *ms;
1340 * First element is not a mapping structure,
1341 * chain must be empty.
1343 if (!IS_MAPPTR(qp)) {
1344 if (qp != qhp || qp != qhp->prev)
1345 fatal("bad phys_table header pointer");
1349 mp = (struct mapping *) qp;
1350 qp = &mp->phys_link;
1351 if (qp->prev != pqp)
1352 fatal("bad phys_link prev pointer");
1353 ms = &mapstate[mp-map_table];
1356 pqp = (queue_entry_t) mp;
1358 } while (IS_MAPPTR(qp));
1360 fatal("bad phys_link next pointer");
1366 struct mapstate *ms;
1372 "vtophys: %s: %c%c%c, hashix %d, physix %d, mapping %x\n",
1374 (ms->flags & M_ISFREE) ? 'F' : '-',
1375 (ms->flags & M_ISHASH) ? 'H' : '-',
1376 (ms->flags & M_ISPHYS) ? 'P' : '-',
1377 ms->hashix, ms->physix, &map_table[ms-mapstate]);
1378 return_to_top_level();
1382 mach_read(str, from, top, size)
1391 from = ksym_lookup(str);
1392 paddr = vtophys(0, from);
1393 if (paddr == ~0 || physrd(paddr, top, size) != 0)
1394 fatal("cannot read %s", str);
1398 mach_malloc(str, size)
1402 char *ptr = (char *) malloc(size);
1405 fatal("no memory for %s", str);
1412 _initialize_hp9k8_dep()
1414 add_com ("process-address", class_obscure, set_paddr_command,
1415 "The process identified by (ps-style) ADDR becomes the\n\
1416 \"current\" process context for kernel debugging.");
1417 add_com_alias ("paddr", "process-address", class_obscure, 0);
1418 add_com ("virtual-to-physical", class_obscure, vtop_command,
1419 "Translates the kernel virtual address ADDR into a physical address.");
1420 add_com_alias ("vtop", "virtual-to-physical", class_obscure, 0);