xref: /original-bsd/sys/hp300/DOC/Debug.tips (revision 16c50d9a)
1*16c50d9aSkarelsNOTE: this description applies to the hp300 system with the old BSD
2*16c50d9aSkarelsvirtual memory system.  It has not been updated to reflect the new,
3*16c50d9aSkarelsMach-derived VM system, but should still be useful.
4*16c50d9aSkarelsThe new system has no fixed-address "u.", but has a fixed mapping
5*16c50d9aSkarelsfor the kernel stack at 0xfff00000.
6*16c50d9aSkarels
7*16c50d9aSkarels--------------------------------------------------------------------------
8*16c50d9aSkarels
93374f4f0SkarelsSome quick notes on the HPBSD VM layout and kernel debugging.
103374f4f0Skarels
113374f4f0SkarelsPhysical memory:
123374f4f0Skarels
133374f4f0SkarelsPhysical memory always ends at the top of the 32 bit address space; i.e. the
143374f4f0Skarelslast addressible byte is at 0xFFFFFFFF.  Hence, the start of physical memory
153374f4f0Skarelsvaries depending on how much memory is installed.  The kernel variable "lowram"
163374f4f0Skarelscontains the starting locatation of memory as provided by the ROM.
173374f4f0Skarels
183374f4f0SkarelsThe low 128k (I think) of the physical address space is occupied by the ROM.
193374f4f0SkarelsThis is accessible via /dev/mem *only* if the kernel is compiled with DEBUG.
203374f4f0Skarels[ Maybe it should always be accessible? ]
213374f4f0Skarels
223374f4f0SkarelsVirtual address spaces:
233374f4f0Skarels
243374f4f0SkarelsThe hardware page size is 4096 bytes.  The hardware uses a two-level lookup.
253374f4f0SkarelsAt the highest level is a one page segment table which maps a page table which
263374f4f0Skarelsmaps the address space.  Each 4 byte segment table entry (described in
273374f4f0Skarelshp300/pte.h) contains the page number of a single page of 4 byte page table
283374f4f0Skarelsentries.  Each PTE maps a single page of address space.  Hence, each STE maps
293374f4f0Skarels4Mb of address space and one page containing 1024 STEs is adequate to map the
303374f4f0Skarelsentire 4Gb address space.
313374f4f0Skarels
323374f4f0SkarelsBoth page and segment table entries look similar.  Both have the page frame
333374f4f0Skarelsin the upper part and control bits in the lower.  This is the opposite of
343374f4f0Skarelsthe VAX.  It is easy to convert the page frame number in an STE/PTE to a
353374f4f0Skarelsphysical address, simply mentally mask out the low 12 bits.  For example
363374f4f0Skarelsif a PTE contains 0xFF880019, the physical memory location mapped starts at
373374f4f0Skarels0xFF880000.
383374f4f0Skarels
393374f4f0SkarelsKernel address space:
403374f4f0Skarels
413374f4f0SkarelsThe kernel resides in its own virtual address space independent of all user
423374f4f0Skarelsprocesses.  When the processor is in supervisor mode (i.e. interrupt or
433374f4f0Skarelsexception handling) it uses the kernel virtual mapping.  The kernel segment
443374f4f0Skarelstable is called Sysseg and is allocated statically in hp300/locore.s.  The
453374f4f0Skarelskernel page table is called Systab is also allocated statically in
463374f4f0Skarelshp300/locore.s and consists of the usual assortment of SYSMAPs.
473374f4f0SkarelsThe size of Systab (Syssize) depends on the configured size of the various
483374f4f0Skarelsmaps but as currently configured is 9216 PTEs.  Both segment and page tables
493374f4f0Skarelsare initialized at bootup in hp300/locore.s.  The segment table never changes
503374f4f0Skarels(except for bits maintained by the hardware).  Portions of the page table
513374f4f0Skarelschange as needed.  The kernel is mapped into the address space starting at 0.
523374f4f0Skarels
533374f4f0SkarelsTheoretically, any address in the range 0 to Syssize * 4096 (0x2400000 as
543374f4f0Skarelscurrently configured) is valid.  However, certain addresses are more common
553374f4f0Skarelsin dumps than others.  Those are (for the current configuration):
563374f4f0Skarels
573374f4f0Skarels	0         - 0x800000	kernel text and permanent data structures
583374f4f0Skarels	0x917000  - 0x91a000	u-area; 1st page is user struct, last k-stack
593374f4f0Skarels	0x1b1b000 - 0x2400000	user page tables, also kmem_alloc()ed data
603374f4f0Skarels
613374f4f0SkarelsUser address space:
623374f4f0Skarels
633374f4f0SkarelsThe user text and data are loaded starting at VA 0.  The user's stack starts
643374f4f0Skarelsat 0xFFF00000 and grows toward lower addresses.  The pages above the user
653374f4f0Skarelsstack are used by the kernel.  From 0xFFF00000 to 0xFFF03000 is the u-area.
663374f4f0SkarelsThe 3 PTEs for this range map (read-only) the same memory as does 0x917000
673374f4f0Skarelsto 0x91a000 in the kernel address space.  This address range is never used
683374f4f0Skarelsby the kernel, but exists for utilities that assume that the u-area sits
693374f4f0Skarelsabove the user stack.  The pages from FFF03000 up are not used.  They
703374f4f0Skarelsexist so that the user stack is in the same location as in HPUX.
713374f4f0Skarels
723374f4f0SkarelsThe user segment table is allocated along with the page tables from Usrptmap.
733374f4f0SkarelsThey are contiguous in kernel VA space with the page tables coming before
743374f4f0Skarelsthe segment table.  Hence, a process has p_szpt+1 pages allocated starting
753374f4f0Skarelsat kernel VA p_p0br.
763374f4f0Skarels
773374f4f0SkarelsThe user segment table is typically very sparse since each entry maps 4Mb.
783374f4f0SkarelsThere are usually only two valid STEs, one at the start mapping the text/data
793374f4f0Skarelspotion of the page table, and one at the end mapping the stack/u-area.  For
803374f4f0Skarelsexample if the segment table was at 0xFFFFA000 there would be valid entries
813374f4f0Skarelsat 0xFFFFA000 and 0xFFFFAFFC.
823374f4f0Skarels
833374f4f0SkarelsRandom notes:
843374f4f0Skarels
853374f4f0SkarelsAn important thing to note is that there are no hardware length registers
863374f4f0Skarelson the HP.  This implies that we cannot "pack" data and stack PTEs into the
873374f4f0Skarelssame page table page.  Hence, every user page table has at least 2 pages
883374f4f0Skarels(3 if you count the segment table).
893374f4f0Skarels
903374f4f0SkarelsThe HP maintains the p0br/p0lr and p1br/p1lr PCB fields the same as the
913374f4f0SkarelsVAX even though they have no meaning to the hardware.  This also keeps many
923374f4f0Skarelsutilities happy.
933374f4f0Skarels
943374f4f0SkarelsThere is no seperate interrupt stack (right now) on the HPs.  Interrupt
953374f4f0Skarelsprocessing is handled on the kernel stack of the "current" process.
963374f4f0Skarels
973374f4f0SkarelsFollowing is a list of things you might want to be able to do with a kernel
983374f4f0Skarelscore dump.  One thing you should always have is a ps listing from the core
993374f4f0Skarelsfile.  Just do:
1003374f4f0Skarels
1013374f4f0Skarels	ps klaw vmunix.? vmcore.?
1023374f4f0Skarels
1033374f4f0SkarelsException related panics (i.e. those detected in hp300/trap.c) will dump
1043374f4f0Skarelsout various useful information before panicing.  If available, you should
1053374f4f0Skarelsget this out of the /usr/adm/messages file.  Finally, you should be in adb:
1063374f4f0Skarels
1073374f4f0Skarels	adb -k vmunix.? vmcore.?
1083374f4f0Skarels
1093374f4f0SkarelsAdb -k will allow you to examine the kernel address space more easily.
1103374f4f0SkarelsIt automatically maps kernel VAs in the range 0 to 0x2400000 to physical
1113374f4f0Skarelsaddresses.  Since the kernel and user address spaces overlap (i.e. both
1123374f4f0Skarelsstart at 0), adb can't let you examine the address space of the "current"
1133374f4f0Skarelsprocess as it does on the VAX.
1143374f4f0Skarels--------
1153374f4f0Skarels
1163374f4f0Skarels1. Find out what the current process was at the time of the crash:
1173374f4f0Skarels
1183374f4f0SkarelsIf you have the dump info from /usr/adm/messages, it should contain the
1193374f4f0SkarelsPID of the active process.  If you don't have this info you can just look
1203374f4f0Skarelsat location "Umap".  This is the PTE for the first page of the u-area; i.e.
1213374f4f0Skarelsthe user structure.  Forget about the last 3 hex digits and compare the top
1223374f4f0Skarels5 to the ADDR column in the ps listing.
1233374f4f0Skarels
1243374f4f0Skarels2. Locating a process' user structure:
1253374f4f0Skarels
1263374f4f0SkarelsGet the ADDR field of the desired process from the ps listing.  This is the
1273374f4f0Skarelspage frame number of the process' user structure.  Tack 3 zeros on to the
1283374f4f0Skarelsend to get the physical address.  Note that this doesn't give you the kernel
1293374f4f0Skarelsstack since it is in a different page than the user-structure and pages of
1303374f4f0Skarelsthe u-area are not physically contiguous.
1313374f4f0Skarels
1323374f4f0Skarels3. Locating a process' proc structure:
1333374f4f0Skarels
1343374f4f0SkarelsFirst find the process' user structure as described above.  Find the u_procp
1353374f4f0Skarelsfield at offset 0x200 from the beginning.  This gives you the kernel VA of
1363374f4f0Skarelsthe proc structure.
1373374f4f0Skarels
1383374f4f0Skarels4. Locating a process' page table:
1393374f4f0Skarels
1403374f4f0SkarelsFirst find the process' user structure as described above.  The first part
1413374f4f0Skarelsof the user structure is the PCB.  The second longword (third field) of the
1423374f4f0SkarelsPCB is pcb_ustp, a pointer to the user segment table.  This pointer is
1433374f4f0Skarelsactually the page frame number.  Again adding 3 zeros yields the physical
1443374f4f0Skarelsaddress.  You can now use the values in the segment table to locate the
1453374f4f0Skarelspage tables.  For example, to locate the first page of the text/data part
1463374f4f0Skarelsof the page table, use the first STE (longword) in the segment table.
1473374f4f0Skarels
1483374f4f0Skarels5. Locating a process' kernel stack:
1493374f4f0Skarels
1503374f4f0SkarelsFirst find the process' page table as described above.  The kernel stack
1513374f4f0Skarelsis near the end of the user address space.  So, locate the last entry in the
1523374f4f0Skarelsuser segment table (base+0xFFC) and use that entry to find the last page of
1533374f4f0Skarelsthe user page table.  Look at the last 256 entries of this page
1543374f4f0Skarels(pagebase+0xFE0)  The first is the PTE for the user-structure.  The second
1553374f4f0Skarelswas intended to be a read-only page to protect the user structure from the
1563374f4f0Skarelskernel stack.  Currently it is read/write and actually allocated.  Hence
1573374f4f0Skarelsit can wind up being a second page for the kernel stack.  The third is the
1583374f4f0Skarelskernel stack.  The last 253 should be zero.  Hence, indirecing through the
1593374f4f0Skarelsthird of these last 256 PTEs will give you the kernel stack page.
1603374f4f0Skarels
1613374f4f0SkarelsAn alternate way to do this is to use the p_addr field of the proc structure
1623374f4f0Skarelswhich is found as described above.  The p_addr field is at offset 0x10 in the
1633374f4f0Skarelsproc structure and points to the first of the PTEs mentioned above (i.e. the
1643374f4f0Skarelsuser structure PTE).
1653374f4f0Skarels
1663374f4f0Skarels6. Interpreting the info in a "trap type N..." panic:
1673374f4f0Skarels
1683374f4f0SkarelsAs mentioned, when the kernel crashes out of hp300/trap.c it will dump some
1693374f4f0Skarelsuseful information.  This dates back to the days when I was debugging the
1703374f4f0Skarelsexception handling code and had no kernel adb or even kernel crash dump code.
1713374f4f0Skarels"trap type" (decimal) is as defined in hp300/trap.h, it doesn't really
1723374f4f0Skarelscorrelate with anything useful.  "code" (hex) is only useful for MMU
1733374f4f0Skarels(trap type 8) errors.  It is the concatination of the MMU status register
1743374f4f0Skarels(see hp300/cpu.h) in the high 16 bits and the 68020 special status word
1753374f4f0Skarels(see the 020 manual page 6-17) in the low 16.  "v" (hex) is the virtual
1763374f4f0Skarelsaddress which caused the fault.  "pid" (decimal) is the ID of the process
1773374f4f0Skarelsrunning at the time of the exception.  Note that if we panic in an interrupt
1783374f4f0Skarelsroutine, this process may not be related to the panic.  "ps" (hex) is the
1793374f4f0Skarelsvalue of the 68020 status register (see page 1-4 of 020 manual) at the time
1803374f4f0Skarelsof the crash.  If the 0x2000 bit is on, we were in supervisor (kernel) mode
1813374f4f0Skarelsat the time, otherwise we were in user mode.  "pc" (hex) is the value of the
1823374f4f0SkarelsPC saved on the hardware exception frame.  It may *not* be the PC of the
1833374f4f0Skarelsinstruction causing the fault (see the 020 manual for details).  The 0x2000
1843374f4f0Skarelsbit of "ps" dictates whether this is a kernel or user VA.  "sfc" and "dfc"
1853374f4f0Skarelsare the 68020 source/destination function codes.  They should always be one.
1863374f4f0Skarels"p0" and "p1" are the VAX-like region registers.  They are of the form:
1873374f4f0Skarels
1883374f4f0Skarels	<length> '@' <kernel VA>
1893374f4f0Skarels
1903374f4f0Skarelswhere both are in hex.  Following these values are a dump of the processor
1913374f4f0Skarelsregisters (hex).  Check the address registers for values close to "v", the
1923374f4f0Skarelsfault address.  Most faults are causes by dereferences of bogus pointers.
1933374f4f0SkarelsMost such dereferences are the result of 020 instructions using the:
1943374f4f0Skarels
1953374f4f0Skarels	<address-register> '@' '(' offset ')'
1963374f4f0Skarels
1973374f4f0Skarelsaddressing mode.  This can help you track down the faulting instruction (since
1983374f4f0Skarelsthe PC may not point to it).  Note that the value of a7 (the stack pointer) is
1993374f4f0SkarelsALWAYS the user SP.  This is brain-dead I know.  Finally, is a dump of the
2003374f4f0Skarelsstack (user/kernel) at the time of the offense.  Before kernel crash dumps,
2013374f4f0Skarelsthis was very useful.
2023374f4f0Skarels
2033374f4f0Skarels7. Converting kernel virtual address to a physical address.
2043374f4f0Skarels
2053374f4f0SkarelsAdb -k already does this for you, but sometimes you want to know what the
2063374f4f0Skarelsresulting physical address is rather than what is there.  Doing this is
2073374f4f0Skarelssimply a matter of indexing into the kernel page table.  In theory we would
2083374f4f0Skarelsfirst have to do a lookup in the kernel segment table, but we know that the
2093374f4f0Skarelskernel page table is physically contiguous so this isn't necessary.  The
2103374f4f0Skarelsbase of the system page table is "Sysmap", so to convert an address V just
2113374f4f0Skarelsdivide the address by 4096 to get the page number, multiply that by 4 (the
2123374f4f0Skarelssize of a PTE in bytes) to get a byte offset, and add that to "Sysmap".
2133374f4f0SkarelsThis gives you the address of the PTE mapping V.  You can then get the
2143374f4f0Skarelsphysical address by masking out the low 12 bits of the contents of that PTE.
2153374f4f0SkarelsTo wit:
2163374f4f0Skarels
2173374f4f0Skarels	*(Sysmap+(VA%1000*4))&fffff000
2183374f4f0Skarels
2193374f4f0Skarelswhere VA is the virtual address in question.
2203374f4f0Skarels
2213374f4f0SkarelsThis technique should also work for user virtual addresses if you replace
2223374f4f0Skarels"Sysmap" with the value of the appropriate processes' P0BR.  This works
2233374f4f0Skarelsbecause a user's page table is *virtually* contiguous in the kernel
2243374f4f0Skarelsstarting at P0BR, and adb will handle translating the kernel virtual addresses
2253374f4f0Skarelsfor you.
226