No empty .Rs/.Re
[netbsd-mini2440.git] / sys / arch / hp300 / DOC / Debug.tips
blob21392868b0aae08dba7dcb38061474023a2eae75
1 $NetBSD: Debug.tips,v 1.3.22.3 2004/09/21 13:15:13 skrll Exp $
3 NOTE: this description applies to the hp300 system with the old BSD
4 virtual memory system.  It has not been updated to reflect the new,
5 Mach-derived VM system, but should still be useful.
6 The new system has no fixed-address "u.", but has a fixed mapping
7 for the kernel stack at 0xfff00000.
9 --------------------------------------------------------------------------
11 Some quick notes on the HPBSD VM layout and kernel debugging.
13 Physical memory:
15 Physical memory always ends at the top of the 32 bit address space; i.e. the
16 last addressible byte is at 0xFFFFFFFF.  Hence, the start of physical memory
17 varies depending on how much memory is installed.  The kernel variable "lowram"
18 contains the starting locatation of memory as provided by the ROM.
20 The low 128k (I think) of the physical address space is occupied by the ROM.
21 This is accessible via /dev/mem *only* if the kernel is compiled with DEBUG.
22 [ Maybe it should always be accessible? ]
24 Virtual address spaces:
26 The hardware page size is 4096 bytes.  The hardware uses a two-level lookup.
27 At the highest level is a one page segment table which maps a page table which
28 maps the address space.  Each 4 byte segment table entry (described in
29 hp300/pte.h) contains the page number of a single page of 4 byte page table
30 entries.  Each PTE maps a single page of address space.  Hence, each STE maps
31 4Mb of address space and one page containing 1024 STEs is adequate to map the
32 entire 4Gb address space.
34 Both page and segment table entries look similar.  Both have the page frame
35 in the upper part and control bits in the lower.  This is the opposite of
36 the VAX.  It is easy to convert the page frame number in an STE/PTE to a
37 physical address, simply mentally mask out the low 12 bits.  For example
38 if a PTE contains 0xFF880019, the physical memory location mapped starts at
39 0xFF880000.
41 Kernel address space:
43 The kernel resides in its own virtual address space independent of all user
44 processes.  When the processor is in supervisor mode (i.e. interrupt or 
45 exception handling) it uses the kernel virtual mapping.  The kernel segment
46 table is called Sysseg and is allocated statically in hp300/locore.s.  The
47 kernel page table is called Systab is also allocated statically in
48 hp300/locore.s and consists of the usual assortment of SYSMAPs.
49 The size of Systab (Syssize) depends on the configured size of the various
50 maps but as currently configured is 9216 PTEs.  Both segment and page tables
51 are initialized at bootup in hp300/locore.s.  The segment table never changes
52 (except for bits maintained by the hardware).  Portions of the page table
53 change as needed.  The kernel is mapped into the address space starting at 0.
55 Theoretically, any address in the range 0 to Syssize * 4096 (0x2400000 as
56 currently configured) is valid.  However, certain addresses are more common
57 in dumps than others.  Those are (for the current configuration):
59         0         - 0x800000    kernel text and permanent data structures
60         0x917000  - 0x91a000    u-area; 1st page is user struct, last k-stack
61         0x1b1b000 - 0x2400000   user page tables, also kmem_alloc()ed data
63 User address space:
65 The user text and data are loaded starting at VA 0.  The user's stack starts
66 at 0xFFF00000 and grows toward lower addresses.  The pages above the user
67 stack are used by the kernel.  From 0xFFF00000 to 0xFFF03000 is the u-area.
68 The 3 PTEs for this range map (read-only) the same memory as does 0x917000
69 to 0x91a000 in the kernel address space.  This address range is never used
70 by the kernel, but exists for utilities that assume that the u-area sits
71 above the user stack.  The pages from FFF03000 up are not used.  They
72 exist so that the user stack is in the same location as in HPUX.
74 The user segment table is allocated along with the page tables from Usrptmap.
75 They are contiguous in kernel VA space with the page tables coming before
76 the segment table.  Hence, a process has p_szpt+1 pages allocated starting
77 at kernel VA p_p0br.
79 The user segment table is typically very sparse since each entry maps 4Mb.
80 There are usually only two valid STEs, one at the start mapping the text/data
81 potion of the page table, and one at the end mapping the stack/u-area.  For
82 example if the segment table was at 0xFFFFA000 there would be valid entries
83 at 0xFFFFA000 and 0xFFFFAFFC.
85 Random notes:
87 An important thing to note is that there are no hardware length registers
88 on the HP.  This implies that we cannot "pack" data and stack PTEs into the
89 same page table page.  Hence, every user page table has at least 2 pages
90 (3 if you count the segment table).
92 The HP maintains the p0br/p0lr and p1br/p1lr PCB fields the same as the
93 VAX even though they have no meaning to the hardware.  This also keeps many
94 utilities happy.
96 There is no separate interrupt stack (right now) on the HPs.  Interrupt
97 processing is handled on the kernel stack of the "current" process.
99 Following is a list of things you might want to be able to do with a kernel
100 core dump.  One thing you should always have is a ps listing from the core
101 file.  Just do:
103         ps klaw vmunix.? vmcore.?
105 Exception related panics (i.e. those detected in hp300/trap.c) will dump
106 out various useful information before panicking.  If available, you should
107 get this out of the /usr/adm/messages file.  Finally, you should be in adb:
109         adb -k vmunix.? vmcore.?
111 Adb -k will allow you to examine the kernel address space more easily.
112 It automatically maps kernel VAs in the range 0 to 0x2400000 to physical
113 addresses.  Since the kernel and user address spaces overlap (i.e. both
114 start at 0), adb can't let you examine the address space of the "current"
115 process as it does on the VAX.
116 --------
118 1. Find out what the current process was at the time of the crash:
120 If you have the dump info from /usr/adm/messages, it should contain the
121 PID of the active process.  If you don't have this info you can just look
122 at location "Umap".  This is the PTE for the first page of the u-area; i.e.
123 the user structure.  Forget about the last 3 hex digits and compare the top
124 5 to the ADDR column in the ps listing.
126 2. Locating a process' user structure:
128 Get the ADDR field of the desired process from the ps listing.  This is the
129 page frame number of the process' user structure.  Tack 3 zeros on to the
130 end to get the physical address.  Note that this doesn't give you the kernel
131 stack since it is in a different page than the user-structure and pages of
132 the u-area are not physically contiguous.
134 3. Locating a process' proc structure:
136 First find the process' user structure as described above.  Find the u_procp
137 field at offset 0x200 from the beginning.  This gives you the kernel VA of
138 the proc structure.
140 4. Locating a process' page table:
142 First find the process' user structure as described above.  The first part
143 of the user structure is the PCB.  The second longword (third field) of the
144 PCB is pcb_ustp, a pointer to the user segment table.  This pointer is
145 actually the page frame number.  Again adding 3 zeros yields the physical
146 address.  You can now use the values in the segment table to locate the
147 page tables.  For example, to locate the first page of the text/data part
148 of the page table, use the first STE (longword) in the segment table.
150 5. Locating a process' kernel stack:
152 First find the process' page table as described above.  The kernel stack
153 is near the end of the user address space.  So, locate the last entry in the
154 user segment table (base+0xFFC) and use that entry to find the last page of
155 the user page table.  Look at the last 256 entries of this page
156 (pagebase+0xFE0)  The first is the PTE for the user-structure.  The second
157 was intended to be a read-only page to protect the user structure from the
158 kernel stack.  Currently it is read/write and actually allocated.  Hence
159 it can wind up being a second page for the kernel stack.  The third is the
160 kernel stack.  The last 253 should be zero.  Hence, indirecing through the
161 third of these last 256 PTEs will give you the kernel stack page.
163 An alternate way to do this is to use the p_addr field of the proc structure
164 which is found as described above.  The p_addr field is at offset 0x10 in the
165 proc structure and points to the first of the PTEs mentioned above (i.e. the
166 user structure PTE).
168 6. Interpreting the info in a "trap type N..." panic:
170 As mentioned, when the kernel crashes out of hp300/trap.c it will dump some
171 useful information.  This dates back to the days when I was debugging the
172 exception handling code and had no kernel adb or even kernel crash dump code.
173 "trap type" (decimal) is as defined in hp300/trap.h, it doesn't really
174 correlate with anything useful.  "code" (hex) is only useful for MMU
175 (trap type 8) errors.  It is the concatination of the MMU status register
176 (see hp300/cpu.h) in the high 16 bits and the 68020 special status word
177 (see the 020 manual page 6-17) in the low 16.  "v" (hex) is the virtual
178 address which caused the fault.  "pid" (decimal) is the ID of the process
179 running at the time of the exception.  Note that if we panic in an interrupt
180 routine, this process may not be related to the panic.  "ps" (hex) is the
181 value of the 68020 status register (see page 1-4 of 020 manual) at the time
182 of the crash.  If the 0x2000 bit is on, we were in supervisor (kernel) mode
183 at the time, otherwise we were in user mode.  "pc" (hex) is the value of the
184 PC saved on the hardware exception frame.  It may *not* be the PC of the
185 instruction causing the fault (see the 020 manual for details).  The 0x2000
186 bit of "ps" dictates whether this is a kernel or user VA.  "sfc" and "dfc"
187 are the 68020 source/destination function codes.  They should always be one.
188 "p0" and "p1" are the VAX-like region registers.  They are of the form:
190         <length> '@' <kernel VA>
192 where both are in hex.  Following these values are a dump of the processor
193 registers (hex).  Check the address registers for values close to "v", the
194 fault address.  Most faults are causes by dereferences of bogus pointers.
195 Most such dereferences are the result of 020 instructions using the:
197         <address-register> '@' '(' offset ')'
199 addressing mode.  This can help you track down the faulting instruction (since
200 the PC may not point to it).  Note that the value of a7 (the stack pointer) is
201 ALWAYS the user SP.  This is brain-dead I know.  Finally, is a dump of the
202 stack (user/kernel) at the time of the offense.  Before kernel crash dumps,
203 this was very useful.
205 7. Converting kernel virtual address to a physical address.
207 Adb -k already does this for you, but sometimes you want to know what the
208 resulting physical address is rather than what is there.  Doing this is
209 simply a matter of indexing into the kernel page table.  In theory we would
210 first have to do a lookup in the kernel segment table, but we know that the
211 kernel page table is physically contiguous so this isn't necessary.  The
212 base of the system page table is "Sysmap", so to convert an address V just
213 divide the address by 4096 to get the page number, multiply that by 4 (the
214 size of a PTE in bytes) to get a byte offset, and add that to "Sysmap".
215 This gives you the address of the PTE mapping V.  You can then get the
216 physical address by masking out the low 12 bits of the contents of that PTE.
217 To wit:
219         *(Sysmap+(VA%1000*4))&fffff000
221 where VA is the virtual address in question.
223 This technique should also work for user virtual addresses if you replace
224 "Sysmap" with the value of the appropriate processes' P0BR.  This works
225 because a user's page table is *virtually* contiguous in the kernel
226 starting at P0BR, and adb will handle translating the kernel virtual addresses
227 for you.