diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2001-08-15 21:24:48 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2001-08-15 21:24:48 +0000 |
commit | ad37f3aeac5764ca6507fb916b178b639b79e2f1 (patch) | |
tree | 59c50ffdceac6052fdd1abd553f5a2c01e9f029c /sys/arch/amiga | |
parent | f83c277e8341259f2ed86951a09673e307593bf0 (diff) |
There is no need explaining how to do manually what libkvm does for you,
and how the HP MMU works, on an arch which doesn't have this MMU.
Diffstat (limited to 'sys/arch/amiga')
-rw-r--r-- | sys/arch/amiga/amiga/DOC/debug | 228 | ||||
-rw-r--r-- | sys/arch/amiga/amiga/DOC/mmu | 148 |
2 files changed, 0 insertions, 376 deletions
diff --git a/sys/arch/amiga/amiga/DOC/debug b/sys/arch/amiga/amiga/DOC/debug deleted file mode 100644 index 9b9ff548329..00000000000 --- a/sys/arch/amiga/amiga/DOC/debug +++ /dev/null @@ -1,228 +0,0 @@ -$OpenBSD: debug,v 1.2 1996/06/04 12:49:16 niklas Exp $ -$NetBSD: debug,v 1.2 1994/10/26 02:02:16 cgd Exp $ - -NOTE: this description applies to the hp300 system with the old BSD -virtual memory system. It has not been updated to reflect the new, -Mach-derived VM system, but should still be useful. -The new system has no fixed-address "u.", but has a fixed mapping -for the kernel stack at 0xfff00000. - --------------------------------------------------------------------------- - -Some quick notes on the HPBSD VM layout and kernel debugging. - -Physical memory: - -Physical memory always ends at the top of the 32 bit address space; i.e. the -last addressible byte is at 0xFFFFFFFF. Hence, the start of physical memory -varies depending on how much memory is installed. The kernel variable "lowram" -contains the starting locatation of memory as provided by the ROM. - -The low 128k (I think) of the physical address space is occupied by the ROM. -This is accessible via /dev/mem *only* if the kernel is compiled with DEBUG. -[ Maybe it should always be accessible? ] - -Virtual address spaces: - -The hardware page size is 4096 bytes. The hardware uses a two-level lookup. -At the highest level is a one page segment table which maps a page table which -maps the address space. Each 4 byte segment table entry (described in -hp300/pte.h) contains the page number of a single page of 4 byte page table -entries. Each PTE maps a single page of address space. Hence, each STE maps -4Mb of address space and one page containing 1024 STEs is adequate to map the -entire 4Gb address space. - -Both page and segment table entries look similar. Both have the page frame -in the upper part and control bits in the lower. This is the opposite of -the VAX. It is easy to convert the page frame number in an STE/PTE to a -physical address, simply mentally mask out the low 12 bits. For example -if a PTE contains 0xFF880019, the physical memory location mapped starts at -0xFF880000. - -Kernel address space: - -The kernel resides in its own virtual address space independent of all user -processes. When the processor is in supervisor mode (i.e. interrupt or -exception handling) it uses the kernel virtual mapping. The kernel segment -table is called Sysseg and is allocated statically in hp300/locore.s. The -kernel page table is called Systab is also allocated statically in -hp300/locore.s and consists of the usual assortment of SYSMAPs. -The size of Systab (Syssize) depends on the configured size of the various -maps but as currently configured is 9216 PTEs. Both segment and page tables -are initialized at bootup in hp300/locore.s. The segment table never changes -(except for bits maintained by the hardware). Portions of the page table -change as needed. The kernel is mapped into the address space starting at 0. - -Theoretically, any address in the range 0 to Syssize * 4096 (0x2400000 as -currently configured) is valid. However, certain addresses are more common -in dumps than others. Those are (for the current configuration): - - 0 - 0x800000 kernel text and permanent data structures - 0x917000 - 0x91a000 u-area; 1st page is user struct, last k-stack - 0x1b1b000 - 0x2400000 user page tables, also kmem_alloc()ed data - -User address space: - -The user text and data are loaded starting at VA 0. The user's stack starts -at 0xFFF00000 and grows toward lower addresses. The pages above the user -stack are used by the kernel. From 0xFFF00000 to 0xFFF03000 is the u-area. -The 3 PTEs for this range map (read-only) the same memory as does 0x917000 -to 0x91a000 in the kernel address space. This address range is never used -by the kernel, but exists for utilities that assume that the u-area sits -above the user stack. The pages from FFF03000 up are not used. They -exist so that the user stack is in the same location as in HPUX. - -The user segment table is allocated along with the page tables from Usrptmap. -They are contiguous in kernel VA space with the page tables coming before -the segment table. Hence, a process has p_szpt+1 pages allocated starting -at kernel VA p_p0br. - -The user segment table is typically very sparse since each entry maps 4Mb. -There are usually only two valid STEs, one at the start mapping the text/data -potion of the page table, and one at the end mapping the stack/u-area. For -example if the segment table was at 0xFFFFA000 there would be valid entries -at 0xFFFFA000 and 0xFFFFAFFC. - -Random notes: - -An important thing to note is that there are no hardware length registers -on the HP. This implies that we cannot "pack" data and stack PTEs into the -same page table page. Hence, every user page table has at least 2 pages -(3 if you count the segment table). - -The HP maintains the p0br/p0lr and p1br/p1lr PCB fields the same as the -VAX even though they have no meaning to the hardware. This also keeps many -utilities happy. - -There is no seperate interrupt stack (right now) on the HPs. Interrupt -processing is handled on the kernel stack of the "current" process. - -Following is a list of things you might want to be able to do with a kernel -core dump. One thing you should always have is a ps listing from the core -file. Just do: - - ps klaw vmunix.? vmcore.? - -Exception related panics (i.e. those detected in hp300/trap.c) will dump -out various useful information before panicing. If available, you should -get this out of the /usr/adm/messages file. Finally, you should be in adb: - - adb -k vmunix.? vmcore.? - -Adb -k will allow you to examine the kernel address space more easily. -It automatically maps kernel VAs in the range 0 to 0x2400000 to physical -addresses. Since the kernel and user address spaces overlap (i.e. both -start at 0), adb can't let you examine the address space of the "current" -process as it does on the VAX. --------- - -1. Find out what the current process was at the time of the crash: - -If you have the dump info from /usr/adm/messages, it should contain the -PID of the active process. If you don't have this info you can just look -at location "Umap". This is the PTE for the first page of the u-area; i.e. -the user structure. Forget about the last 3 hex digits and compare the top -5 to the ADDR column in the ps listing. - -2. Locating a process' user structure: - -Get the ADDR field of the desired process from the ps listing. This is the -page frame number of the process' user structure. Tack 3 zeros on to the -end to get the physical address. Note that this doesn't give you the kernel -stack since it is in a different page than the user-structure and pages of -the u-area are not physically contiguous. - -3. Locating a process' proc structure: - -First find the process' user structure as described above. Find the u_procp -field at offset 0x200 from the beginning. This gives you the kernel VA of -the proc structure. - -4. Locating a process' page table: - -First find the process' user structure as described above. The first part -of the user structure is the PCB. The second longword (third field) of the -PCB is pcb_ustp, a pointer to the user segment table. This pointer is -actually the page frame number. Again adding 3 zeros yields the physical -address. You can now use the values in the segment table to locate the -page tables. For example, to locate the first page of the text/data part -of the page table, use the first STE (longword) in the segment table. - -5. Locating a process' kernel stack: - -First find the process' page table as described above. The kernel stack -is near the end of the user address space. So, locate the last entry in the -user segment table (base+0xFFC) and use that entry to find the last page of -the user page table. Look at the last 256 entries of this page -(pagebase+0xFE0) The first is the PTE for the user-structure. The second -was intended to be a read-only page to protect the user structure from the -kernel stack. Currently it is read/write and actually allocated. Hence -it can wind up being a second page for the kernel stack. The third is the -kernel stack. The last 253 should be zero. Hence, indirecing through the -third of these last 256 PTEs will give you the kernel stack page. - -An alternate way to do this is to use the p_addr field of the proc structure -which is found as described above. The p_addr field is at offset 0x10 in the -proc structure and points to the first of the PTEs mentioned above (i.e. the -user structure PTE). - -6. Interpreting the info in a "trap type N..." panic: - -As mentioned, when the kernel crashes out of hp300/trap.c it will dump some -useful information. This dates back to the days when I was debugging the -exception handling code and had no kernel adb or even kernel crash dump code. -"trap type" (decimal) is as defined in hp300/trap.h, it doesn't really -correlate with anything useful. "code" (hex) is only useful for MMU -(trap type 8) errors. It is the concatination of the MMU status register -(see hp300/cpu.h) in the high 16 bits and the 68020 special status word -(see the 020 manual page 6-17) in the low 16. "v" (hex) is the virtual -address which caused the fault. "pid" (decimal) is the ID of the process -running at the time of the exception. Note that if we panic in an interrupt -routine, this process may not be related to the panic. "ps" (hex) is the -value of the 68020 status register (see page 1-4 of 020 manual) at the time -of the crash. If the 0x2000 bit is on, we were in supervisor (kernel) mode -at the time, otherwise we were in user mode. "pc" (hex) is the value of the -PC saved on the hardware exception frame. It may *not* be the PC of the -instruction causing the fault (see the 020 manual for details). The 0x2000 -bit of "ps" dictates whether this is a kernel or user VA. "sfc" and "dfc" -are the 68020 source/destination function codes. They should always be one. -"p0" and "p1" are the VAX-like region registers. They are of the form: - - <length> '@' <kernel VA> - -where both are in hex. Following these values are a dump of the processor -registers (hex). Check the address registers for values close to "v", the -fault address. Most faults are causes by dereferences of bogus pointers. -Most such dereferences are the result of 020 instructions using the: - - <address-register> '@' '(' offset ')' - -addressing mode. This can help you track down the faulting instruction (since -the PC may not point to it). Note that the value of a7 (the stack pointer) is -ALWAYS the user SP. This is brain-dead I know. Finally, is a dump of the -stack (user/kernel) at the time of the offense. Before kernel crash dumps, -this was very useful. - -7. Converting kernel virtual address to a physical address. - -Adb -k already does this for you, but sometimes you want to know what the -resulting physical address is rather than what is there. Doing this is -simply a matter of indexing into the kernel page table. In theory we would -first have to do a lookup in the kernel segment table, but we know that the -kernel page table is physically contiguous so this isn't necessary. The -base of the system page table is "Sysmap", so to convert an address V just -divide the address by 4096 to get the page number, multiply that by 4 (the -size of a PTE in bytes) to get a byte offset, and add that to "Sysmap". -This gives you the address of the PTE mapping V. You can then get the -physical address by masking out the low 12 bits of the contents of that PTE. -To wit: - - *(Sysmap+(VA%1000*4))&fffff000 - -where VA is the virtual address in question. - -This technique should also work for user virtual addresses if you replace -"Sysmap" with the value of the appropriate processes' P0BR. This works -because a user's page table is *virtually* contiguous in the kernel -starting at P0BR, and adb will handle translating the kernel virtual addresses -for you. diff --git a/sys/arch/amiga/amiga/DOC/mmu b/sys/arch/amiga/amiga/DOC/mmu deleted file mode 100644 index 1ea632aa4c1..00000000000 --- a/sys/arch/amiga/amiga/DOC/mmu +++ /dev/null @@ -1,148 +0,0 @@ -$OpenBSD: mmu,v 1.2 1996/06/04 12:49:16 niklas Exp $ -$NetBSD: mmu,v 1.2 1994/10/26 02:02:18 cgd Exp $ - -Overview: --------- - - (Some of this is gleaned from an article in the September 1986 - Hewlett-Packard Journal and info in the July 1987 HP Communicator) - - Page and segment table entries mimic the Motorola 68851 PMMU, - in an effort at upward compatibility. The HP MMU uses a two - level translation scheme. There are seperate (but equal!) - translation tables for both supervisor and user modes. At the - lowest level are page tables. Each page table consists of one - or more 4k pages of 1024x4 byte page table entries. Each PTE - maps one 4k page of VA space. At the highest level is the - segment table. The segment table is a single 4K page of 1024x4 - byte entries. Each entry points to a 4k page of PTEs. Hence - one STE maps 4Mb of VA space and one page of STEs is sufficient - to map the entire 4Gb address space (what a coincidence!). The - unused valid bit in page and segment table entries must be - zero. - - There are seperate translation lookaside buffers for the user - and supervisor modes, each containing 1024 entries. - - To augment the 68020's instruction cache, the HP CPU has an - external cache. A logical cache implementation is used with 16 - Kbytes of cache on 320 systems and 32 Kbytes on 350 systems. - Each cache entry can contain instructions or data, from either - user or supervisor space. Seperate valid bits are kept for - user and supervisor entries, allowing for descriminatory - flushing of the cache. - - MMU translation and cache-miss detection are done in parallel. - - -Segment table entries: -------- ----- ------- - - bits 31-12: Physical page frame number of PT page - bits 11-4: Reserved at zero - (can software use them?) - bit 3: Reserved at one - bit 2: Set to 1 if segment is read-only, ow read-write - bits 1-0: Valid bits - (hardware uses bit 1) - - -Page table entries: ----- ----- ------- - - bits 31-12: Physical page frame number of page - bits 11-7: Available for software use - bit 6: If 1, inhibits caching of data in this page. - (both instruction and external cache) - bit 5: Reserved at zero - bit 4: Hardware modify bit - bit 3: Hardware reference bit - bit 2: Set to 1 if page is read-only, ow read-write - bits 1-0: Valid bits - (hardware uses bit 0) - - -Hardware registers: --------- --------- - - The hardware has four longword registers controlling the MMU. - The registers can be accessed as shortwords also (remember to - add 2 to addresses given below). - - 5F4000: Supervisor mode segment table pointer. Loaded (as longword) - with page frame number (i.e. Physaddr >> 12) of the segment - table mapping supervisor space. - 5F4004: User mode segment table pointer. Loaded (as longword) with - page frame number of the segment table mapping user space. - 5F4008: TLB control register. Used to invalid large sections of the - TLB. More info below. - 5F400C: MMU command/status register. Defined as follows: - - bit 15: If 1, indicates a page table fault occured - bit 14: If 1, indicates a page fault occured - bit 13: If 1, indicates a protection fault (write to RO page) - bit 6: MC68881 enable. Tied to chip enable line. - (set this bit to enable) - bit 5: MC68020 instruction cache enable. Tied to Insruction - cache disable line. (set this bit to enable) - bit 3: If 1, indicates an MMU related bus error occured. - Bits 13-15 are now valid. - bit 2: External cache enable. (set this bit to enable) - bit 1: Supervisor mapping enable. Enables translation of - supervisor space VAs. - bit 0: User mapping enable. Enables translation of user - space VAs. - - - Any bits set by the hardware are cleared only by software. - (i.e. bits 3,13,14,15) - -Invalidating TLB: ------------- --- - - All translations: - Read the TLB control register (5F4008) as a longword. - - User translations only: - Write a longword 0 to TLB register or set the user - segment table pointer. - - Supervisor translations only: - Write a longword 0x8000 to TLB register or set the - supervisor segment table pointer. - - A particular VA translation: - Set destination function code to 3 ("purge" space), - write a longword 0 to the VA whose translation we are to - invalidate, and restore function code. This apparently - invalidates any translation for that VA in both the user - and supervisor LB. Here is what I did: - - #define FC_PURGE 3 - #define FC_USERD 1 - _TBIS: - movl sp@(4),a0 | VA to invalidate - moveq #FC_PURGE,d0 | change address space - movc d0,dfc | for destination - moveq #0,d0 | zero to invalidate? - movsl d0,a0@ | hit it - moveq #FC_USERD,d0 | back to old - movc d0,dfc | address space - rts | done - - -Invalidating the external cache: ------------- --- -------- ----- - - Everything: - Toggle the cache enable bit (bit 2) in the MMU control - register (5F400C). Can be done by ANDing and ORing the - register location. - - User: - Change the user segment table pointer register (5F4004), - i.e. read the current value and write it back. - - Supervisor: - Change the supervisor segment table pointer register - (5F4000), i.e. read the current value and write it back. |