11.6Sandvar$NetBSD: Debug.tips,v 1.6 2023/09/08 19:04:28 andvar Exp $
21.2Scgd
31.1SmycroftNOTE: this description applies to the hp300 system with the old BSD
41.1Smycroftvirtual memory system.  It has not been updated to reflect the new,
51.1SmycroftMach-derived VM system, but should still be useful.
61.1SmycroftThe new system has no fixed-address "u.", but has a fixed mapping
71.1Smycroftfor the kernel stack at 0xfff00000.
81.1Smycroft
91.1Smycroft--------------------------------------------------------------------------
101.1Smycroft
111.1SmycroftSome quick notes on the HPBSD VM layout and kernel debugging.
121.1Smycroft
131.1SmycroftPhysical memory:
141.1Smycroft
151.1SmycroftPhysical memory always ends at the top of the 32 bit address space; i.e. the
161.6Sandvarlast addressable byte is at 0xFFFFFFFF.  Hence, the start of physical memory
171.1Smycroftvaries depending on how much memory is installed.  The kernel variable "lowram"
181.6Sandvarcontains the starting location of memory as provided by the ROM.
191.1Smycroft
201.1SmycroftThe low 128k (I think) of the physical address space is occupied by the ROM.
211.1SmycroftThis is accessible via /dev/mem *only* if the kernel is compiled with DEBUG.
221.1Smycroft[ Maybe it should always be accessible? ]
231.1Smycroft
241.1SmycroftVirtual address spaces:
251.1Smycroft
261.1SmycroftThe hardware page size is 4096 bytes.  The hardware uses a two-level lookup.
271.1SmycroftAt the highest level is a one page segment table which maps a page table which
281.1Smycroftmaps the address space.  Each 4 byte segment table entry (described in
291.1Smycrofthp300/pte.h) contains the page number of a single page of 4 byte page table
301.1Smycroftentries.  Each PTE maps a single page of address space.  Hence, each STE maps
311.1Smycroft4Mb of address space and one page containing 1024 STEs is adequate to map the
321.1Smycroftentire 4Gb address space.
331.1Smycroft
341.1SmycroftBoth page and segment table entries look similar.  Both have the page frame
351.1Smycroftin the upper part and control bits in the lower.  This is the opposite of
361.1Smycroftthe VAX.  It is easy to convert the page frame number in an STE/PTE to a
371.1Smycroftphysical address, simply mentally mask out the low 12 bits.  For example
381.1Smycroftif a PTE contains 0xFF880019, the physical memory location mapped starts at
391.1Smycroft0xFF880000.
401.1Smycroft
411.1SmycroftKernel address space:
421.1Smycroft
431.1SmycroftThe kernel resides in its own virtual address space independent of all user
441.1Smycroftprocesses.  When the processor is in supervisor mode (i.e. interrupt or 
451.1Smycroftexception handling) it uses the kernel virtual mapping.  The kernel segment
461.1Smycrofttable is called Sysseg and is allocated statically in hp300/locore.s.  The
471.1Smycroftkernel page table is called Systab is also allocated statically in
481.1Smycrofthp300/locore.s and consists of the usual assortment of SYSMAPs.
491.1SmycroftThe size of Systab (Syssize) depends on the configured size of the various
501.1Smycroftmaps but as currently configured is 9216 PTEs.  Both segment and page tables
511.1Smycroftare initialized at bootup in hp300/locore.s.  The segment table never changes
521.1Smycroft(except for bits maintained by the hardware).  Portions of the page table
531.1Smycroftchange as needed.  The kernel is mapped into the address space starting at 0.
541.1Smycroft
551.1SmycroftTheoretically, any address in the range 0 to Syssize * 4096 (0x2400000 as
561.1Smycroftcurrently configured) is valid.  However, certain addresses are more common
571.1Smycroftin dumps than others.  Those are (for the current configuration):
581.1Smycroft
591.1Smycroft	0         - 0x800000	kernel text and permanent data structures
601.1Smycroft	0x917000  - 0x91a000	u-area; 1st page is user struct, last k-stack
611.1Smycroft	0x1b1b000 - 0x2400000	user page tables, also kmem_alloc()ed data
621.1Smycroft
631.1SmycroftUser address space:
641.1Smycroft
651.1SmycroftThe user text and data are loaded starting at VA 0.  The user's stack starts
661.1Smycroftat 0xFFF00000 and grows toward lower addresses.  The pages above the user
671.1Smycroftstack are used by the kernel.  From 0xFFF00000 to 0xFFF03000 is the u-area.
681.1SmycroftThe 3 PTEs for this range map (read-only) the same memory as does 0x917000
691.1Smycroftto 0x91a000 in the kernel address space.  This address range is never used
701.1Smycroftby the kernel, but exists for utilities that assume that the u-area sits
711.1Smycroftabove the user stack.  The pages from FFF03000 up are not used.  They
721.1Smycroftexist so that the user stack is in the same location as in HPUX.
731.1Smycroft
741.1SmycroftThe user segment table is allocated along with the page tables from Usrptmap.
751.1SmycroftThey are contiguous in kernel VA space with the page tables coming before
761.1Smycroftthe segment table.  Hence, a process has p_szpt+1 pages allocated starting
771.1Smycroftat kernel VA p_p0br.
781.1Smycroft
791.1SmycroftThe user segment table is typically very sparse since each entry maps 4Mb.
801.1SmycroftThere are usually only two valid STEs, one at the start mapping the text/data
811.1Smycroftpotion of the page table, and one at the end mapping the stack/u-area.  For
821.1Smycroftexample if the segment table was at 0xFFFFA000 there would be valid entries
831.1Smycroftat 0xFFFFA000 and 0xFFFFAFFC.
841.1Smycroft
851.1SmycroftRandom notes:
861.1Smycroft
871.1SmycroftAn important thing to note is that there are no hardware length registers
881.1Smycrofton the HP.  This implies that we cannot "pack" data and stack PTEs into the
891.1Smycroftsame page table page.  Hence, every user page table has at least 2 pages
901.1Smycroft(3 if you count the segment table).
911.1Smycroft
921.1SmycroftThe HP maintains the p0br/p0lr and p1br/p1lr PCB fields the same as the
931.1SmycroftVAX even though they have no meaning to the hardware.  This also keeps many
941.1Smycroftutilities happy.
951.1Smycroft
961.3SwizThere is no separate interrupt stack (right now) on the HPs.  Interrupt
971.1Smycroftprocessing is handled on the kernel stack of the "current" process.
981.1Smycroft
991.1SmycroftFollowing is a list of things you might want to be able to do with a kernel
1001.1Smycroftcore dump.  One thing you should always have is a ps listing from the core
1011.1Smycroftfile.  Just do:
1021.1Smycroft
1031.1Smycroft	ps klaw vmunix.? vmcore.?
1041.1Smycroft
1051.1SmycroftException related panics (i.e. those detected in hp300/trap.c) will dump
1061.4Swizout various useful information before panicking.  If available, you should
1071.1Smycroftget this out of the /usr/adm/messages file.  Finally, you should be in adb:
1081.1Smycroft
1091.1Smycroft	adb -k vmunix.? vmcore.?
1101.1Smycroft
1111.1SmycroftAdb -k will allow you to examine the kernel address space more easily.
1121.1SmycroftIt automatically maps kernel VAs in the range 0 to 0x2400000 to physical
1131.1Smycroftaddresses.  Since the kernel and user address spaces overlap (i.e. both
1141.1Smycroftstart at 0), adb can't let you examine the address space of the "current"
1151.1Smycroftprocess as it does on the VAX.
1161.1Smycroft--------
1171.1Smycroft
1181.1Smycroft1. Find out what the current process was at the time of the crash:
1191.1Smycroft
1201.1SmycroftIf you have the dump info from /usr/adm/messages, it should contain the
1211.1SmycroftPID of the active process.  If you don't have this info you can just look
1221.1Smycroftat location "Umap".  This is the PTE for the first page of the u-area; i.e.
1231.1Smycroftthe user structure.  Forget about the last 3 hex digits and compare the top
1241.1Smycroft5 to the ADDR column in the ps listing.
1251.1Smycroft
1261.1Smycroft2. Locating a process' user structure:
1271.1Smycroft
1281.1SmycroftGet the ADDR field of the desired process from the ps listing.  This is the
1291.1Smycroftpage frame number of the process' user structure.  Tack 3 zeros on to the
1301.1Smycroftend to get the physical address.  Note that this doesn't give you the kernel
1311.1Smycroftstack since it is in a different page than the user-structure and pages of
1321.1Smycroftthe u-area are not physically contiguous.
1331.1Smycroft
1341.1Smycroft3. Locating a process' proc structure:
1351.1Smycroft
1361.1SmycroftFirst find the process' user structure as described above.  Find the u_procp
1371.1Smycroftfield at offset 0x200 from the beginning.  This gives you the kernel VA of
1381.1Smycroftthe proc structure.
1391.1Smycroft
1401.1Smycroft4. Locating a process' page table:
1411.1Smycroft
1421.1SmycroftFirst find the process' user structure as described above.  The first part
1431.1Smycroftof the user structure is the PCB.  The second longword (third field) of the
1441.1SmycroftPCB is pcb_ustp, a pointer to the user segment table.  This pointer is
1451.1Smycroftactually the page frame number.  Again adding 3 zeros yields the physical
1461.1Smycroftaddress.  You can now use the values in the segment table to locate the
1471.1Smycroftpage tables.  For example, to locate the first page of the text/data part
1481.1Smycroftof the page table, use the first STE (longword) in the segment table.
1491.1Smycroft
1501.1Smycroft5. Locating a process' kernel stack:
1511.1Smycroft
1521.1SmycroftFirst find the process' page table as described above.  The kernel stack
1531.1Smycroftis near the end of the user address space.  So, locate the last entry in the
1541.1Smycroftuser segment table (base+0xFFC) and use that entry to find the last page of
1551.1Smycroftthe user page table.  Look at the last 256 entries of this page
1561.1Smycroft(pagebase+0xFE0)  The first is the PTE for the user-structure.  The second
1571.1Smycroftwas intended to be a read-only page to protect the user structure from the
1581.1Smycroftkernel stack.  Currently it is read/write and actually allocated.  Hence
1591.1Smycroftit can wind up being a second page for the kernel stack.  The third is the
1601.6Sandvarkernel stack.  The last 253 should be zero.  Hence, indirecting through the
1611.1Smycroftthird of these last 256 PTEs will give you the kernel stack page.
1621.1Smycroft
1631.1SmycroftAn alternate way to do this is to use the p_addr field of the proc structure
1641.1Smycroftwhich is found as described above.  The p_addr field is at offset 0x10 in the
1651.1Smycroftproc structure and points to the first of the PTEs mentioned above (i.e. the
1661.1Smycroftuser structure PTE).
1671.1Smycroft
1681.1Smycroft6. Interpreting the info in a "trap type N..." panic:
1691.1Smycroft
1701.1SmycroftAs mentioned, when the kernel crashes out of hp300/trap.c it will dump some
1711.1Smycroftuseful information.  This dates back to the days when I was debugging the
1721.1Smycroftexception handling code and had no kernel adb or even kernel crash dump code.
1731.1Smycroft"trap type" (decimal) is as defined in hp300/trap.h, it doesn't really
1741.1Smycroftcorrelate with anything useful.  "code" (hex) is only useful for MMU
1751.6Sandvar(trap type 8) errors.  It is the concatenation of the MMU status register
1761.1Smycroft(see hp300/cpu.h) in the high 16 bits and the 68020 special status word
1771.1Smycroft(see the 020 manual page 6-17) in the low 16.  "v" (hex) is the virtual
1781.1Smycroftaddress which caused the fault.  "pid" (decimal) is the ID of the process
1791.1Smycroftrunning at the time of the exception.  Note that if we panic in an interrupt
1801.1Smycroftroutine, this process may not be related to the panic.  "ps" (hex) is the
1811.1Smycroftvalue of the 68020 status register (see page 1-4 of 020 manual) at the time
1821.1Smycroftof the crash.  If the 0x2000 bit is on, we were in supervisor (kernel) mode
1831.1Smycroftat the time, otherwise we were in user mode.  "pc" (hex) is the value of the
1841.1SmycroftPC saved on the hardware exception frame.  It may *not* be the PC of the
1851.1Smycroftinstruction causing the fault (see the 020 manual for details).  The 0x2000
1861.1Smycroftbit of "ps" dictates whether this is a kernel or user VA.  "sfc" and "dfc"
1871.1Smycroftare the 68020 source/destination function codes.  They should always be one.
1881.1Smycroft"p0" and "p1" are the VAX-like region registers.  They are of the form:
1891.1Smycroft
1901.1Smycroft	<length> '@' <kernel VA>
1911.1Smycroft
1921.1Smycroftwhere both are in hex.  Following these values are a dump of the processor
1931.1Smycroftregisters (hex).  Check the address registers for values close to "v", the
1941.1Smycroftfault address.  Most faults are causes by dereferences of bogus pointers.
1951.1SmycroftMost such dereferences are the result of 020 instructions using the:
1961.1Smycroft
1971.1Smycroft	<address-register> '@' '(' offset ')'
1981.1Smycroft
1991.1Smycroftaddressing mode.  This can help you track down the faulting instruction (since
2001.1Smycroftthe PC may not point to it).  Note that the value of a7 (the stack pointer) is
2011.1SmycroftALWAYS the user SP.  This is brain-dead I know.  Finally, is a dump of the
2021.1Smycroftstack (user/kernel) at the time of the offense.  Before kernel crash dumps,
2031.1Smycroftthis was very useful.
2041.1Smycroft
2051.1Smycroft7. Converting kernel virtual address to a physical address.
2061.1Smycroft
2071.1SmycroftAdb -k already does this for you, but sometimes you want to know what the
2081.1Smycroftresulting physical address is rather than what is there.  Doing this is
2091.1Smycroftsimply a matter of indexing into the kernel page table.  In theory we would
2101.1Smycroftfirst have to do a lookup in the kernel segment table, but we know that the
2111.1Smycroftkernel page table is physically contiguous so this isn't necessary.  The
2121.1Smycroftbase of the system page table is "Sysmap", so to convert an address V just
2131.1Smycroftdivide the address by 4096 to get the page number, multiply that by 4 (the
2141.1Smycroftsize of a PTE in bytes) to get a byte offset, and add that to "Sysmap".
2151.1SmycroftThis gives you the address of the PTE mapping V.  You can then get the
2161.1Smycroftphysical address by masking out the low 12 bits of the contents of that PTE.
2171.1SmycroftTo wit:
2181.1Smycroft
2191.1Smycroft	*(Sysmap+(VA%1000*4))&fffff000
2201.1Smycroft
2211.1Smycroftwhere VA is the virtual address in question.
2221.1Smycroft
2231.1SmycroftThis technique should also work for user virtual addresses if you replace
2241.1Smycroft"Sysmap" with the value of the appropriate processes' P0BR.  This works
2251.1Smycroftbecause a user's page table is *virtually* contiguous in the kernel
2261.1Smycroftstarting at P0BR, and adb will handle translating the kernel virtual addresses
2271.1Smycroftfor you.
228