diff options
| author | Adrian Bunk <bunk@kernel.org> | 2008-02-03 08:54:28 -0500 |
|---|---|---|
| committer | Adrian Bunk <bunk@kernel.org> | 2008-02-03 08:54:28 -0500 |
| commit | 0868ff7a4215f9244037b63a2952761cbe196a07 (patch) | |
| tree | b98be929b6972a03c550166eea0ea17afc926058 /Documentation/frv | |
| parent | 03502faa259bce35317a32afe79b7c69f507e14a (diff) | |
move frv docs one level up
My first guess for "fujitsu" was it might be related to the
fujitsu-laptop.c driver...
Move the frv directory one level up since frv is the name of the
architecture in the Linux kernel.
Signed-off-by: Adrian Bunk <bunk@kernel.org>
Diffstat (limited to 'Documentation/frv')
| -rw-r--r-- | Documentation/frv/README.txt | 51 | ||||
| -rw-r--r-- | Documentation/frv/atomic-ops.txt | 134 | ||||
| -rw-r--r-- | Documentation/frv/booting.txt | 181 | ||||
| -rw-r--r-- | Documentation/frv/clock.txt | 65 | ||||
| -rw-r--r-- | Documentation/frv/configuring.txt | 125 | ||||
| -rw-r--r-- | Documentation/frv/features.txt | 310 | ||||
| -rw-r--r-- | Documentation/frv/gdbinit | 102 | ||||
| -rw-r--r-- | Documentation/frv/gdbstub.txt | 130 | ||||
| -rw-r--r-- | Documentation/frv/kernel-ABI.txt | 262 | ||||
| -rw-r--r-- | Documentation/frv/mmu-layout.txt | 306 |
10 files changed, 1666 insertions, 0 deletions
diff --git a/Documentation/frv/README.txt b/Documentation/frv/README.txt new file mode 100644 index 000000000000..a984faa968e8 --- /dev/null +++ b/Documentation/frv/README.txt | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | ================================ | ||
| 2 | Fujitsu FR-V LINUX DOCUMENTATION | ||
| 3 | ================================ | ||
| 4 | |||
| 5 | This directory contains documentation for the Fujitsu FR-V CPU architecture | ||
| 6 | port of Linux. | ||
| 7 | |||
| 8 | The following documents are available: | ||
| 9 | |||
| 10 | (*) features.txt | ||
| 11 | |||
| 12 | A description of the basic features inherent in this architecture port. | ||
| 13 | |||
| 14 | |||
| 15 | (*) configuring.txt | ||
| 16 | |||
| 17 | A summary of the configuration options particular to this architecture. | ||
| 18 | |||
| 19 | |||
| 20 | (*) booting.txt | ||
| 21 | |||
| 22 | A description of how to boot the kernel image and a summary of the kernel | ||
| 23 | command line options. | ||
| 24 | |||
| 25 | |||
| 26 | (*) gdbstub.txt | ||
| 27 | |||
| 28 | A description of how to debug the kernel using GDB attached by serial | ||
| 29 | port, and a summary of the services available. | ||
| 30 | |||
| 31 | |||
| 32 | (*) mmu-layout.txt | ||
| 33 | |||
| 34 | A description of the virtual and physical memory layout used in the | ||
| 35 | MMU linux kernel, and the registers used to support it. | ||
| 36 | |||
| 37 | |||
| 38 | (*) gdbinit | ||
| 39 | |||
| 40 | An example .gdbinit file for use with GDB. It includes macros for viewing | ||
| 41 | MMU state on the FR451. See mmu-layout.txt for more information. | ||
| 42 | |||
| 43 | |||
| 44 | (*) clock.txt | ||
| 45 | |||
| 46 | A description of the CPU clock scaling interface. | ||
| 47 | |||
| 48 | |||
| 49 | (*) atomic-ops.txt | ||
| 50 | |||
| 51 | A description of how the FR-V kernel's atomic operations work. | ||
diff --git a/Documentation/frv/atomic-ops.txt b/Documentation/frv/atomic-ops.txt new file mode 100644 index 000000000000..96638e9b9fe0 --- /dev/null +++ b/Documentation/frv/atomic-ops.txt | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | ===================================== | ||
| 2 | FUJITSU FR-V KERNEL ATOMIC OPERATIONS | ||
| 3 | ===================================== | ||
| 4 | |||
| 5 | On the FR-V CPUs, there is only one atomic Read-Modify-Write operation: the SWAP/SWAPI | ||
| 6 | instruction. Unfortunately, this alone can't be used to implement the following operations: | ||
| 7 | |||
| 8 | (*) Atomic add to memory | ||
| 9 | |||
| 10 | (*) Atomic subtract from memory | ||
| 11 | |||
| 12 | (*) Atomic bit modification (set, clear or invert) | ||
| 13 | |||
| 14 | (*) Atomic compare and exchange | ||
| 15 | |||
| 16 | On such CPUs, the standard way of emulating such operations in uniprocessor mode is to disable | ||
| 17 | interrupts, but on the FR-V CPUs, modifying the PSR takes a lot of clock cycles, and it has to be | ||
| 18 | done twice. This means the CPU runs for a relatively long time with interrupts disabled, | ||
| 19 | potentially having a great effect on interrupt latency. | ||
| 20 | |||
| 21 | |||
| 22 | ============= | ||
| 23 | NEW ALGORITHM | ||
| 24 | ============= | ||
| 25 | |||
| 26 | To get around this, the following algorithm has been implemented. It operates in a way similar to | ||
| 27 | the LL/SC instruction pairs supported on a number of platforms. | ||
| 28 | |||
| 29 | (*) The CCCR.CC3 register is reserved within the kernel to act as an atomic modify abort flag. | ||
| 30 | |||
| 31 | (*) In the exception prologues run on kernel->kernel entry, CCCR.CC3 is set to 0 (Undefined | ||
| 32 | state). | ||
| 33 | |||
| 34 | (*) All atomic operations can then be broken down into the following algorithm: | ||
| 35 | |||
| 36 | (1) Set ICC3.Z to true and set CC3 to True (ORCC/CKEQ/ORCR). | ||
| 37 | |||
| 38 | (2) Load the value currently in the memory to be modified into a register. | ||
| 39 | |||
| 40 | (3) Make changes to the value. | ||
| 41 | |||
| 42 | (4) If CC3 is still True, simultaneously and atomically (by VLIW packing): | ||
| 43 | |||
| 44 | (a) Store the modified value back to memory. | ||
| 45 | |||
| 46 | (b) Set ICC3.Z to false (CORCC on GR29 is sufficient for this - GR29 holds the current | ||
| 47 | task pointer in the kernel, and so is guaranteed to be non-zero). | ||
| 48 | |||
| 49 | (5) If ICC3.Z is still true, go back to step (1). | ||
| 50 | |||
| 51 | This works in a non-SMP environment because any interrupt or other exception that happens between | ||
| 52 | steps (1) and (4) will set CC3 to the Undefined, thus aborting the store in (4a), and causing the | ||
| 53 | condition in ICC3 to remain with the Z flag set, thus causing step (5) to loop back to step (1). | ||
| 54 | |||
| 55 | |||
| 56 | This algorithm suffers from two problems: | ||
| 57 | |||
| 58 | (1) The condition CCCR.CC3 is cleared unconditionally by an exception, irrespective of whether or | ||
| 59 | not any changes were made to the target memory location during that exception. | ||
| 60 | |||
| 61 | (2) The branch from step (5) back to step (1) may have to happen more than once until the store | ||
| 62 | manages to take place. In theory, this loop could cycle forever because there are too many | ||
| 63 | interrupts coming in, but it's unlikely. | ||
| 64 | |||
| 65 | |||
| 66 | ======= | ||
| 67 | EXAMPLE | ||
| 68 | ======= | ||
| 69 | |||
| 70 | Taking an example from include/asm-frv/atomic.h: | ||
| 71 | |||
| 72 | static inline int atomic_add_return(int i, atomic_t *v) | ||
| 73 | { | ||
| 74 | unsigned long val; | ||
| 75 | |||
| 76 | asm("0: \n" | ||
| 77 | |||
| 78 | It starts by setting ICC3.Z to true for later use, and also transforming that into CC3 being in the | ||
| 79 | True state. | ||
| 80 | |||
| 81 | " orcc gr0,gr0,gr0,icc3 \n" <-- (1) | ||
| 82 | " ckeq icc3,cc7 \n" <-- (1) | ||
| 83 | |||
| 84 | Then it does the load. Note that the final phase of step (1) is done at the same time as the | ||
| 85 | load. The VLIW packing ensures they are done simultaneously. The ".p" on the load must not be | ||
| 86 | removed without swapping the order of these two instructions. | ||
| 87 | |||
| 88 | " ld.p %M0,%1 \n" <-- (2) | ||
| 89 | " orcr cc7,cc7,cc3 \n" <-- (1) | ||
| 90 | |||
| 91 | Then the proposed modification is generated. Note that the old value can be retained if required | ||
| 92 | (such as in test_and_set_bit()). | ||
| 93 | |||
| 94 | " add%I2 %1,%2,%1 \n" <-- (3) | ||
| 95 | |||
| 96 | Then it attempts to store the value back, contingent on no exception having cleared CC3 since it | ||
| 97 | was set to True. | ||
| 98 | |||
| 99 | " cst.p %1,%M0 ,cc3,#1 \n" <-- (4a) | ||
| 100 | |||
| 101 | It simultaneously records the success or failure of the store in ICC3.Z. | ||
| 102 | |||
| 103 | " corcc gr29,gr29,gr0 ,cc3,#1 \n" <-- (4b) | ||
| 104 | |||
| 105 | Such that the branch can then be taken if the operation was aborted. | ||
| 106 | |||
| 107 | " beq icc3,#0,0b \n" <-- (5) | ||
| 108 | : "+U"(v->counter), "=&r"(val) | ||
| 109 | : "NPr"(i) | ||
| 110 | : "memory", "cc7", "cc3", "icc3" | ||
| 111 | ); | ||
| 112 | |||
| 113 | return val; | ||
| 114 | } | ||
| 115 | |||
| 116 | |||
| 117 | ============= | ||
| 118 | CONFIGURATION | ||
| 119 | ============= | ||
| 120 | |||
| 121 | The atomic ops implementation can be made inline or out-of-line by changing the | ||
| 122 | CONFIG_FRV_OUTOFLINE_ATOMIC_OPS configuration variable. Making it out-of-line has a number of | ||
| 123 | advantages: | ||
| 124 | |||
| 125 | - The resulting kernel image may be smaller | ||
| 126 | - Debugging is easier as atomic ops can just be stepped over and they can be breakpointed | ||
| 127 | |||
| 128 | Keeping it inline also has a number of advantages: | ||
| 129 | |||
| 130 | - The resulting kernel may be Faster | ||
| 131 | - no out-of-line function calls need to be made | ||
| 132 | - the compiler doesn't have half its registers clobbered by making a call | ||
| 133 | |||
| 134 | The out-of-line implementations live in arch/frv/lib/atomic-ops.S. | ||
diff --git a/Documentation/frv/booting.txt b/Documentation/frv/booting.txt new file mode 100644 index 000000000000..ace200b7c214 --- /dev/null +++ b/Documentation/frv/booting.txt | |||
| @@ -0,0 +1,181 @@ | |||
| 1 | ========================= | ||
| 2 | BOOTING FR-V LINUX KERNEL | ||
| 3 | ========================= | ||
| 4 | |||
| 5 | ====================== | ||
| 6 | PROVIDING A FILESYSTEM | ||
| 7 | ====================== | ||
| 8 | |||
| 9 | First of all, a root filesystem must be made available. This can be done in | ||
| 10 | one of two ways: | ||
| 11 | |||
| 12 | (1) NFS Export | ||
| 13 | |||
| 14 | A filesystem should be constructed in a directory on an NFS server that | ||
| 15 | the target board can reach. This directory should then be NFS exported | ||
| 16 | such that the target board can read and write into it as root. | ||
| 17 | |||
| 18 | (2) Flash Filesystem (JFFS2 Recommended) | ||
| 19 | |||
| 20 | In this case, the image must be stored or built up on flash before it | ||
| 21 | can be used. A complete image can be built using the mkfs.jffs2 or | ||
| 22 | similar program and then downloaded and stored into flash by RedBoot. | ||
| 23 | |||
| 24 | |||
| 25 | ======================== | ||
| 26 | LOADING THE KERNEL IMAGE | ||
| 27 | ======================== | ||
| 28 | |||
| 29 | The kernel will need to be loaded into RAM by RedBoot (or by some alternative | ||
| 30 | boot loader) before it can be run. The kernel image (arch/frv/boot/Image) may | ||
| 31 | be loaded in one of three ways: | ||
| 32 | |||
| 33 | (1) Load from Flash | ||
| 34 | |||
| 35 | This is the simplest. RedBoot can store an image in the flash (see the | ||
| 36 | RedBoot documentation) and then load it back into RAM. RedBoot keeps | ||
| 37 | track of the load address, entry point and size, so the command to do | ||
| 38 | this is simply: | ||
| 39 | |||
| 40 | fis load linux | ||
| 41 | |||
| 42 | The image is then ready to be executed. | ||
| 43 | |||
| 44 | (2) Load by TFTP | ||
| 45 | |||
| 46 | The following command will download a raw binary kernel image from the | ||
| 47 | default server (as negotiated by BOOTP) and store it into RAM: | ||
| 48 | |||
| 49 | load -b 0x00100000 -r /tftpboot/image.bin | ||
| 50 | |||
| 51 | The image is then ready to be executed. | ||
| 52 | |||
| 53 | (3) Load by Y-Modem | ||
| 54 | |||
| 55 | The following command will download a raw binary kernel image across the | ||
| 56 | serial port that RedBoot is currently using: | ||
| 57 | |||
| 58 | load -m ymodem -b 0x00100000 -r zImage | ||
| 59 | |||
| 60 | The serial client (such as minicom) must then be told to transmit the | ||
| 61 | program by Y-Modem. | ||
| 62 | |||
| 63 | When finished, the image will then be ready to be executed. | ||
| 64 | |||
| 65 | |||
| 66 | ================== | ||
| 67 | BOOTING THE KERNEL | ||
| 68 | ================== | ||
| 69 | |||
| 70 | Boot the image with the following RedBoot command: | ||
| 71 | |||
| 72 | exec -c "<CMDLINE>" 0x00100000 | ||
| 73 | |||
| 74 | For example: | ||
| 75 | |||
| 76 | exec -c "console=ttySM0,115200 ip=:::::dhcp root=/dev/mtdblock2 rw" | ||
| 77 | |||
| 78 | This will start the kernel running. Note that if the GDB-stub is compiled in, | ||
| 79 | then the kernel will immediately wait for GDB to connect over serial before | ||
| 80 | doing anything else. See the section on kernel debugging with GDB. | ||
| 81 | |||
| 82 | The kernel command line <CMDLINE> tells the kernel where its console is and | ||
| 83 | how to find its root filesystem. This is made up of the following components, | ||
| 84 | separated by spaces: | ||
| 85 | |||
| 86 | (*) console=ttyS<x>[,<baud>[<parity>[<bits>[<flow>]]]] | ||
| 87 | |||
| 88 | This specifies that the system console should output through on-chip | ||
| 89 | serial port <x> (which can be "0" or "1"). | ||
| 90 | |||
| 91 | <baud> is a standard baud rate between 1200 and 115200 (default 9600). | ||
| 92 | |||
| 93 | <parity> is a parity setting of "N", "O", "E", "M" or "S" for None, Odd, | ||
| 94 | Even, Mark or Space. "None" is the default. | ||
| 95 | |||
| 96 | <stop> is "7" or "8" for the number of bits per character. "8" is the | ||
| 97 | default. | ||
| 98 | |||
| 99 | <flow> is "r" to use flow control (XCTS on serial port 2 only). The | ||
| 100 | default is to not use flow control. | ||
| 101 | |||
| 102 | For example: | ||
| 103 | |||
| 104 | console=ttyS0,115200 | ||
| 105 | |||
| 106 | To use the first on-chip serial port at baud rate 115200, no parity, 8 | ||
| 107 | bits, and no flow control. | ||
| 108 | |||
| 109 | (*) root=/dev/<xxxx> | ||
| 110 | |||
| 111 | This specifies the device upon which the root filesystem resides. For | ||
| 112 | example: | ||
| 113 | |||
| 114 | /dev/nfs NFS root filesystem | ||
| 115 | /dev/mtdblock3 Fourth RedBoot partition on the System Flash | ||
| 116 | |||
| 117 | (*) rw | ||
| 118 | |||
| 119 | Start with the root filesystem mounted Read/Write. | ||
| 120 | |||
| 121 | The remaining components are all optional: | ||
| 122 | |||
| 123 | (*) ip=<ip>::::<host>:<iface>:<cfg> | ||
| 124 | |||
| 125 | Configure the network interface. If <cfg> is "off" then <ip> should | ||
| 126 | specify the IP address for the network device <iface>. <host> provide | ||
| 127 | the hostname for the device. | ||
| 128 | |||
| 129 | If <cfg> is "bootp" or "dhcp", then all of these parameters will be | ||
| 130 | discovered by consulting a BOOTP or DHCP server. | ||
| 131 | |||
| 132 | For example, the following might be used: | ||
| 133 | |||
| 134 | ip=192.168.73.12::::frv:eth0:off | ||
| 135 | |||
| 136 | This sets the IP address on the VDK motherboard RTL8029 ethernet chipset | ||
| 137 | (eth0) to be 192.168.73.12, and sets the board's hostname to be "frv". | ||
| 138 | |||
| 139 | (*) nfsroot=<server>:<dir>[,v<vers>] | ||
| 140 | |||
| 141 | This is mandatory if "root=/dev/nfs" is given as an option. It tells the | ||
| 142 | kernel the IP address of the NFS server providing its root filesystem, | ||
| 143 | and the pathname on that server of the filesystem. | ||
| 144 | |||
| 145 | The NFS version to use can also be specified. v2 and v3 are supported by | ||
| 146 | Linux. | ||
| 147 | |||
| 148 | For example: | ||
| 149 | |||
| 150 | nfsroot=192.168.73.1:/nfsroot-frv | ||
| 151 | |||
| 152 | (*) profile=1 | ||
| 153 | |||
| 154 | Turns on the kernel profiler (accessible through /proc/profile). | ||
| 155 | |||
| 156 | (*) console=gdb0 | ||
| 157 | |||
| 158 | This can be used as an alternative to the "console=ttyS..." listed | ||
| 159 | above. I tells the kernel to pass the console output to GDB if the | ||
| 160 | gdbstub is compiled in to the kernel. | ||
| 161 | |||
| 162 | If this is used, then the gdbstub passes the text to GDB, which then | ||
| 163 | simply dumps it to its standard output. | ||
| 164 | |||
| 165 | (*) mem=<xxx>M | ||
| 166 | |||
| 167 | Normally the kernel will work out how much SDRAM it has by reading the | ||
| 168 | SDRAM controller registers. That can be overridden with this | ||
| 169 | option. This allows the kernel to be told that it has <xxx> megabytes of | ||
| 170 | memory available. | ||
| 171 | |||
| 172 | (*) init=<prog> [<arg> [<arg> [<arg> ...]]] | ||
| 173 | |||
| 174 | This tells the kernel what program to run initially. By default this is | ||
| 175 | /sbin/init, but /sbin/sash or /bin/sh are common alternatives. | ||
| 176 | |||
| 177 | (*) vdc=... | ||
| 178 | |||
| 179 | This option configures the MB93493 companion chip visual display | ||
| 180 | driver. Please see Documentation/frv/mb93493/vdc.txt for more | ||
| 181 | information. | ||
diff --git a/Documentation/frv/clock.txt b/Documentation/frv/clock.txt new file mode 100644 index 000000000000..c72d350e177a --- /dev/null +++ b/Documentation/frv/clock.txt | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | Clock scaling | ||
| 2 | ------------- | ||
| 3 | |||
| 4 | The kernel supports scaling of CLCK.CMODE, CLCK.CM and CLKC.P0 clock | ||
| 5 | registers. If built with CONFIG_PM and CONFIG_SYSCTL options enabled, four | ||
| 6 | extra files will appear in the directory /proc/sys/pm/. Reading these files | ||
| 7 | will show: | ||
| 8 | |||
| 9 | p0 -- current value of the P0 bit in CLKC register. | ||
| 10 | cm -- current value of the CM bits in CLKC register. | ||
| 11 | cmode -- current value of the CMODE bits in CLKC register. | ||
| 12 | |||
| 13 | On all boards, the 'p0' file should also be writable, and either '1' or '0' | ||
| 14 | can be rewritten, to set or clear the CLKC_P0 bit respectively, hence | ||
| 15 | controlling whether the resource bus rate clock is halved. | ||
| 16 | |||
| 17 | The 'cm' file should also be available on all boards. '0' can be written to it | ||
| 18 | to shift the board into High-Speed mode (normal), and '1' can be written to | ||
| 19 | shift the board into Medium-Speed mode. Selecting Low-Speed mode is not | ||
| 20 | supported by this interface, even though some CPUs do support it. | ||
| 21 | |||
| 22 | On the boards with FR405 CPU (i.e. CB60 and CB70), the 'cmode' file is also | ||
| 23 | writable, allowing the CPU core speed (and other clock speeds) to be | ||
| 24 | controlled from userspace. | ||
| 25 | |||
| 26 | |||
| 27 | Determining current and possible settings | ||
| 28 | ----------------------------------------- | ||
| 29 | |||
| 30 | The current state and the available masks can be found in /proc/cpuinfo. For | ||
| 31 | example, on the CB70: | ||
| 32 | |||
| 33 | # cat /proc/cpuinfo | ||
| 34 | CPU-Series: fr400 | ||
| 35 | CPU-Core: fr405, gr0-31, BE, CCCR | ||
| 36 | CPU: mb93405 | ||
| 37 | MMU: Prot | ||
| 38 | FP-Media: fr0-31, Media | ||
| 39 | System: mb93091-cb70, mb93090-mb00 | ||
| 40 | PM-Controls: cmode=0xd31f, cm=0x3, p0=0x3, suspend=0x9 | ||
| 41 | PM-Status: cmode=3, cm=0, p0=0 | ||
| 42 | Clock-In: 50.00 MHz | ||
| 43 | Clock-Core: 300.00 MHz | ||
| 44 | Clock-SDRAM: 100.00 MHz | ||
| 45 | Clock-CBus: 100.00 MHz | ||
| 46 | Clock-Res: 50.00 MHz | ||
| 47 | Clock-Ext: 50.00 MHz | ||
| 48 | Clock-DSU: 25.00 MHz | ||
| 49 | BogoMips: 300.00 | ||
| 50 | |||
| 51 | And on the PDK, the PM lines look like the following: | ||
| 52 | |||
| 53 | PM-Controls: cm=0x3, p0=0x3, suspend=0x9 | ||
| 54 | PM-Status: cmode=9, cm=0, p0=0 | ||
| 55 | |||
| 56 | The PM-Controls line, if present, will indicate which /proc/sys/pm files can | ||
| 57 | be set to what values. The specification values are bitmasks; so, for example, | ||
| 58 | "suspend=0x9" indicates that 0 and 3 can be written validly to | ||
| 59 | /proc/sys/pm/suspend. | ||
| 60 | |||
| 61 | The PM-Controls line will only be present if CONFIG_PM is configured to Y. | ||
| 62 | |||
| 63 | The PM-Status line indicates which clock controls are set to which value. If | ||
| 64 | the file can be read, then the suspend value must be 0, and so that's not | ||
| 65 | included. | ||
diff --git a/Documentation/frv/configuring.txt b/Documentation/frv/configuring.txt new file mode 100644 index 000000000000..36e76a2336fa --- /dev/null +++ b/Documentation/frv/configuring.txt | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | ======================================= | ||
| 2 | FUJITSU FR-V LINUX KERNEL CONFIGURATION | ||
| 3 | ======================================= | ||
| 4 | |||
| 5 | ===================== | ||
| 6 | CONFIGURATION OPTIONS | ||
| 7 | ===================== | ||
| 8 | |||
| 9 | The most important setting is in the "MMU support options" tab (the first | ||
| 10 | presented in the configuration tools available): | ||
| 11 | |||
| 12 | (*) "Kernel Type" | ||
| 13 | |||
| 14 | This options allows selection of normal, MMU-requiring linux, and uClinux | ||
| 15 | (which doesn't require an MMU and doesn't have inter-process protection). | ||
| 16 | |||
| 17 | There are a number of settings in the "Processor type and features" section of | ||
| 18 | the kernel configuration that need to be considered. | ||
| 19 | |||
| 20 | (*) "CPU" | ||
| 21 | |||
| 22 | The register and instruction sets at the core of the processor. This can | ||
| 23 | only be set to "FR40x/45x/55x" at the moment - but this permits usage of | ||
| 24 | the kernel with MB93091 CB10, CB11, CB30, CB41, CB60, CB70 and CB451 | ||
| 25 | CPU boards, and with the MB93093 PDK board. | ||
| 26 | |||
| 27 | (*) "System" | ||
| 28 | |||
| 29 | This option allows a choice of basic system. This governs the peripherals | ||
| 30 | that are expected to be available. | ||
| 31 | |||
| 32 | (*) "Motherboard" | ||
| 33 | |||
| 34 | This specifies the type of motherboard being used, and the peripherals | ||
| 35 | upon it. Currently only "MB93090-MB00" can be set here. | ||
| 36 | |||
| 37 | (*) "Default cache-write mode" | ||
| 38 | |||
| 39 | This controls the initial data cache write management mode. By default | ||
| 40 | Write-Through is selected, but Write-Back (Copy-Back) can also be | ||
| 41 | selected. This can be changed dynamically once the kernel is running (see | ||
| 42 | features.txt). | ||
| 43 | |||
| 44 | There are some architecture specific configuration options in the "General | ||
| 45 | Setup" section of the kernel configuration too: | ||
| 46 | |||
| 47 | (*) "Reserve memory uncached for (PCI) DMA" | ||
| 48 | |||
| 49 | This requests that a uClinux kernel set aside some memory in an uncached | ||
| 50 | window for the use as consistent DMA memory (mainly for PCI). At least a | ||
| 51 | megabyte will be allocated in this way, possibly more. Any memory so | ||
| 52 | reserved will not be available for normal allocations. | ||
| 53 | |||
| 54 | (*) "Kernel support for ELF-FDPIC binaries" | ||
| 55 | |||
| 56 | This enables the binary-format driver for the new FDPIC ELF binaries that | ||
| 57 | this platform normally uses. These binaries are totally relocatable - | ||
| 58 | their separate sections can relocated independently, allowing them to be | ||
| 59 | shared on uClinux where possible. This should normally be enabled. | ||
| 60 | |||
| 61 | (*) "Kernel image protection" | ||
| 62 | |||
| 63 | This makes the protection register governing access to the core kernel | ||
| 64 | image prohibit access by userspace programs. This option is available on | ||
| 65 | uClinux only. | ||
| 66 | |||
| 67 | There are also a number of settings in the "Kernel Hacking" section of the | ||
| 68 | kernel configuration especially for debugging a kernel on this | ||
| 69 | architecture. See the "gdbstub.txt" file for information about those. | ||
| 70 | |||
| 71 | |||
| 72 | ====================== | ||
| 73 | DEFAULT CONFIGURATIONS | ||
| 74 | ====================== | ||
| 75 | |||
| 76 | The kernel sources include a number of example default configurations: | ||
| 77 | |||
| 78 | (*) defconfig-mb93091 | ||
| 79 | |||
| 80 | Default configuration for the MB93091-VDK with both CPU board and | ||
| 81 | MB93090-MB00 motherboard running uClinux. | ||
| 82 | |||
| 83 | |||
| 84 | (*) defconfig-mb93091-fb | ||
| 85 | |||
| 86 | Default configuration for the MB93091-VDK with CPU board, | ||
| 87 | MB93090-MB00 motherboard, and DAV board running uClinux. | ||
| 88 | Includes framebuffer driver. | ||
| 89 | |||
| 90 | |||
| 91 | (*) defconfig-mb93093 | ||
| 92 | |||
| 93 | Default configuration for the MB93093-PDK board running uClinux. | ||
| 94 | |||
| 95 | |||
| 96 | (*) defconfig-cb70-standalone | ||
| 97 | |||
| 98 | Default configuration for the MB93091-VDK with only CB70 CPU board | ||
| 99 | running uClinux. This will use the CB70's DM9000 for network access. | ||
| 100 | |||
| 101 | |||
| 102 | (*) defconfig-mmu | ||
| 103 | |||
| 104 | Default configuration for the MB93091-VDK with both CB451 CPU board and | ||
| 105 | MB93090-MB00 motherboard running MMU linux. | ||
| 106 | |||
| 107 | (*) defconfig-mmu-audio | ||
| 108 | |||
| 109 | Default configuration for the MB93091-VDK with CB451 CPU board, DAV | ||
| 110 | board, and MB93090-MB00 motherboard running MMU linux. Includes | ||
| 111 | audio driver. | ||
| 112 | |||
| 113 | (*) defconfig-mmu-fb | ||
| 114 | |||
| 115 | Default configuration for the MB93091-VDK with CB451 CPU board, DAV | ||
| 116 | board, and MB93090-MB00 motherboard running MMU linux. Includes | ||
| 117 | framebuffer driver. | ||
| 118 | |||
| 119 | (*) defconfig-mmu-standalone | ||
| 120 | |||
| 121 | Default configuration for the MB93091-VDK with only CB451 CPU board | ||
| 122 | running MMU linux. | ||
| 123 | |||
| 124 | |||
| 125 | |||
diff --git a/Documentation/frv/features.txt b/Documentation/frv/features.txt new file mode 100644 index 000000000000..fa20c0e72833 --- /dev/null +++ b/Documentation/frv/features.txt | |||
| @@ -0,0 +1,310 @@ | |||
| 1 | =========================== | ||
| 2 | FUJITSU FR-V LINUX FEATURES | ||
| 3 | =========================== | ||
| 4 | |||
| 5 | This kernel port has a number of features of which the user should be aware: | ||
| 6 | |||
| 7 | (*) Linux and uClinux | ||
| 8 | |||
| 9 | The FR-V architecture port supports both normal MMU linux and uClinux out | ||
| 10 | of the same sources. | ||
| 11 | |||
| 12 | |||
| 13 | (*) CPU support | ||
| 14 | |||
| 15 | Support for the FR401, FR403, FR405, FR451 and FR555 CPUs should work with | ||
| 16 | the same uClinux kernel configuration. | ||
| 17 | |||
| 18 | In normal (MMU) Linux mode, only the FR451 CPU will work as that is the | ||
| 19 | only one with a suitably featured CPU. | ||
| 20 | |||
| 21 | The kernel is written and compiled with the assumption that only the | ||
| 22 | bottom 32 GR registers and no FR registers will be used by the kernel | ||
| 23 | itself, however all extra userspace registers will be saved on context | ||
| 24 | switch. Note that since most CPUs can't support lazy switching, no attempt | ||
| 25 | is made to do lazy register saving where that would be possible (FR555 | ||
| 26 | only currently). | ||
| 27 | |||
| 28 | |||
| 29 | (*) Board support | ||
| 30 | |||
| 31 | The board on which the kernel will run can be configured on the "Processor | ||
| 32 | type and features" configuration tab. | ||
| 33 | |||
| 34 | Set the System to "MB93093-PDK" to boot from the MB93093 (FR403) PDK. | ||
| 35 | |||
| 36 | Set the System to "MB93091-VDK" to boot from the CB11, CB30, CB41, CB60, | ||
| 37 | CB70 or CB451 VDK boards. Set the Motherboard setting to "MB93090-MB00" to | ||
| 38 | boot with the standard ATA90590B VDK motherboard, and set it to "None" to | ||
| 39 | boot without any motherboard. | ||
| 40 | |||
| 41 | |||
| 42 | (*) Binary Formats | ||
| 43 | |||
| 44 | The only userspace binary format supported is FDPIC ELF. Normal ELF, FLAT | ||
| 45 | and AOUT binaries are not supported for this architecture. | ||
| 46 | |||
| 47 | FDPIC ELF supports shared library and program interpreter facilities. | ||
| 48 | |||
| 49 | |||
| 50 | (*) Scheduler Speed | ||
| 51 | |||
| 52 | The kernel scheduler runs at 100Hz irrespective of the clock speed on this | ||
| 53 | architecture. This value is set in asm/param.h (see the HZ macro defined | ||
| 54 | there). | ||
| 55 | |||
| 56 | |||
| 57 | (*) Normal (MMU) Linux Memory Layout. | ||
| 58 | |||
| 59 | See mmu-layout.txt in this directory for a description of the normal linux | ||
| 60 | memory layout | ||
| 61 | |||
| 62 | See include/asm-frv/mem-layout.h for constants pertaining to the memory | ||
| 63 | layout. | ||
| 64 | |||
| 65 | See include/asm-frv/mb-regs.h for the constants pertaining to the I/O bus | ||
| 66 | controller configuration. | ||
| 67 | |||
| 68 | |||
| 69 | (*) uClinux Memory Layout | ||
| 70 | |||
| 71 | The memory layout used by the uClinux kernel is as follows: | ||
| 72 | |||
| 73 | 0x00000000 - 0x00000FFF Null pointer catch page | ||
| 74 | 0x20000000 - 0x200FFFFF CS2# [PDK] FPGA | ||
| 75 | 0xC0000000 - 0xCFFFFFFF SDRAM | ||
| 76 | 0xC0000000 Base of Linux kernel image | ||
| 77 | 0xE0000000 - 0xEFFFFFFF CS2# [VDK] SLBUS/PCI window | ||
| 78 | 0xF0000000 - 0xF0FFFFFF CS5# MB93493 CSC area (DAV daughter board) | ||
| 79 | 0xF1000000 - 0xF1FFFFFF CS7# [CB70/CB451] CPU-card PCMCIA port space | ||
| 80 | 0xFC000000 - 0xFC0FFFFF CS1# [VDK] MB86943 config space | ||
| 81 | 0xFC100000 - 0xFC1FFFFF CS6# [CB70/CB451] CPU-card DM9000 NIC space | ||
| 82 | 0xFC100000 - 0xFC1FFFFF CS6# [PDK] AX88796 NIC space | ||
| 83 | 0xFC200000 - 0xFC2FFFFF CS3# MB93493 CSR area (DAV daughter board) | ||
| 84 | 0xFD000000 - 0xFDFFFFFF CS4# [CB70/CB451] CPU-card extra flash space | ||
| 85 | 0xFE000000 - 0xFEFFFFFF Internal CPU peripherals | ||
| 86 | 0xFF000000 - 0xFF1FFFFF CS0# Flash 1 | ||
| 87 | 0xFF200000 - 0xFF3FFFFF CS0# Flash 2 | ||
| 88 | 0xFFC00000 - 0xFFC0001F CS0# [VDK] FPGA | ||
| 89 | |||
| 90 | The kernel reads the size of the SDRAM from the memory bus controller | ||
| 91 | registers by default. | ||
| 92 | |||
| 93 | The kernel initialisation code (1) adjusts the SDRAM base addresses to | ||
| 94 | move the SDRAM to desired address, (2) moves the kernel image down to the | ||
| 95 | bottom of SDRAM, (3) adjusts the bus controller registers to move I/O | ||
| 96 | windows, and (4) rearranges the protection registers to protect all of | ||
| 97 | this. | ||
| 98 | |||
| 99 | The reasons for doing this are: (1) the page at address 0 should be | ||
| 100 | inaccessible so that NULL pointer errors can be caught; and (2) the bottom | ||
| 101 | three quarters are left unoccupied so that an FR-V CPU with an MMU can use | ||
| 102 | it for virtual userspace mappings. | ||
| 103 | |||
| 104 | See include/asm-frv/mem-layout.h for constants pertaining to the memory | ||
| 105 | layout. | ||
| 106 | |||
| 107 | See include/asm-frv/mb-regs.h for the constants pertaining to the I/O bus | ||
| 108 | controller configuration. | ||
| 109 | |||
| 110 | |||
| 111 | (*) uClinux Memory Protection | ||
| 112 | |||
| 113 | A DAMPR register is used to cover the entire region used for I/O | ||
| 114 | (0xE0000000 - 0xFFFFFFFF). This permits the kernel to make uncached | ||
| 115 | accesses to this region. Userspace is not permitted to access it. | ||
| 116 | |||
| 117 | The DAMPR/IAMPR protection registers not in use for any other purpose are | ||
| 118 | tiled over the top of the SDRAM such that: | ||
| 119 | |||
| 120 | (1) The core kernel image is covered by as small a tile as possible | ||
| 121 | granting only the kernel access to the underlying data, whilst | ||
| 122 | making sure no SDRAM is actually made unavailable by this approach. | ||
| 123 | |||
| 124 | (2) All other tiles are arranged to permit userspace access to the rest | ||
| 125 | of the SDRAM. | ||
| 126 | |||
| 127 | Barring point (1), there is nothing to protect kernel data against | ||
| 128 | userspace damage - but this is uClinux. | ||
| 129 | |||
| 130 | |||
| 131 | (*) Exceptions and Fixups | ||
| 132 | |||
| 133 | Since the FR40x and FR55x CPUs that do not have full MMUs generate | ||
| 134 | imprecise data error exceptions, there are currently no automatic fixup | ||
| 135 | services available in uClinux. This includes misaligned memory access | ||
| 136 | fixups. | ||
| 137 | |||
| 138 | Userspace EFAULT errors can be trapped by issuing a MEMBAR instruction and | ||
| 139 | forcing the fault to happen there. | ||
| 140 | |||
| 141 | On the FR451, however, data exceptions are mostly precise, and so | ||
| 142 | exception fixup handling is implemented as normal. | ||
| 143 | |||
| 144 | |||
| 145 | (*) Userspace Breakpoints | ||
| 146 | |||
| 147 | The ptrace() system call supports the following userspace debugging | ||
| 148 | features: | ||
| 149 | |||
| 150 | (1) Hardware assisted single step. | ||
| 151 | |||
| 152 | (2) Breakpoint via the FR-V "BREAK" instruction. | ||
| 153 | |||
| 154 | (3) Breakpoint via the FR-V "TIRA GR0, #1" instruction. | ||
| 155 | |||
| 156 | (4) Syscall entry/exit trap. | ||
| 157 | |||
| 158 | Each of the above generates a SIGTRAP. | ||
| 159 | |||
| 160 | |||
| 161 | (*) On-Chip Serial Ports | ||
| 162 | |||
| 163 | The FR-V on-chip serial ports are made available as ttyS0 and ttyS1. Note | ||
| 164 | that if the GDB stub is compiled in, ttyS1 will not actually be available | ||
| 165 | as it will be being used for the GDB stub. | ||
| 166 | |||
| 167 | These ports can be made by: | ||
| 168 | |||
| 169 | mknod /dev/ttyS0 c 4 64 | ||
| 170 | mknod /dev/ttyS1 c 4 65 | ||
| 171 | |||
| 172 | |||
| 173 | (*) Maskable Interrupts | ||
| 174 | |||
| 175 | Level 15 (Non-maskable) interrupts are dealt with by the GDB stub if | ||
| 176 | present, and cause a panic if not. If the GDB stub is present, ttyS1's | ||
| 177 | interrupts are rated at level 15. | ||
| 178 | |||
| 179 | All other interrupts are distributed over the set of available priorities | ||
| 180 | so that no IRQs are shared where possible. The arch interrupt handling | ||
| 181 | routines attempt to disentangle the various sources available through the | ||
| 182 | CPU's own multiplexor, and those on off-CPU peripherals. | ||
| 183 | |||
| 184 | |||
| 185 | (*) Accessing PCI Devices | ||
| 186 | |||
| 187 | Where PCI is available, care must be taken when dealing with drivers that | ||
| 188 | access PCI devices. PCI devices present their data in little-endian form, | ||
| 189 | but the CPU sees it in big-endian form. The macros in asm/io.h try to get | ||
| 190 | this right, but may not under all circumstances... | ||
| 191 | |||
| 192 | |||
| 193 | (*) Ax88796 Ethernet Driver | ||
| 194 | |||
| 195 | The MB93093 PDK board has an Ax88796 ethernet chipset (an NE2000 clone). A | ||
| 196 | driver has been written to deal specifically with this. The driver | ||
| 197 | provides MII services for the card. | ||
| 198 | |||
| 199 | The driver can be configured by running make xconfig, and going to: | ||
| 200 | |||
| 201 | (*) Network device support | ||
| 202 | - turn on "Network device support" | ||
| 203 | (*) Ethernet (10 or 100Mbit) | ||
| 204 | - turn on "Ethernet (10 or 100Mbit)" | ||
| 205 | - turn on "AX88796 NE2000 compatible chipset" | ||
| 206 | |||
| 207 | The driver can be found in: | ||
| 208 | |||
| 209 | drivers/net/ax88796.c | ||
| 210 | include/asm/ax88796.h | ||
| 211 | |||
| 212 | |||
| 213 | (*) WorkRAM Driver | ||
| 214 | |||
| 215 | This driver provides a character device that permits access to the WorkRAM | ||
| 216 | that can be found on the FR451 CPU. Each page is accessible through a | ||
| 217 | separate minor number, thereby permitting each page to have its own | ||
| 218 | filesystem permissions set on the device file. | ||
| 219 | |||
| 220 | The device files should be: | ||
| 221 | |||
| 222 | mknod /dev/frv/workram0 c 240 0 | ||
| 223 | mknod /dev/frv/workram1 c 240 1 | ||
| 224 | mknod /dev/frv/workram2 c 240 2 | ||
| 225 | ... | ||
| 226 | |||
| 227 | The driver will not permit the opening of any device file that does not | ||
| 228 | correspond to at least a partial page of WorkRAM. So the first device file | ||
| 229 | is the only one available on the FR451. If any other CPU is detected, none | ||
| 230 | of the devices will be openable. | ||
| 231 | |||
| 232 | The devices can be accessed with read, write and llseek, and can also be | ||
| 233 | mmapped. If they're mmapped, they will only map at the appropriate | ||
| 234 | 0x7e8nnnnn address on linux and at the 0xfe8nnnnn address on uClinux. If | ||
| 235 | MAP_FIXED is not specified, the appropriate address will be chosen anyway. | ||
| 236 | |||
| 237 | The mappings must be MAP_SHARED not MAP_PRIVATE, and must not be | ||
| 238 | PROT_EXEC. They must also start at file offset 0, and must not be longer | ||
| 239 | than one page in size. | ||
| 240 | |||
| 241 | This driver can be configured by running make xconfig, and going to: | ||
| 242 | |||
| 243 | (*) Character devices | ||
| 244 | - turn on "Fujitsu FR-V CPU WorkRAM support" | ||
| 245 | |||
| 246 | |||
| 247 | (*) Dynamic data cache write mode changing | ||
| 248 | |||
| 249 | It is possible to view and to change the data cache's write mode through | ||
| 250 | the /proc/sys/frv/cache-mode file while the kernel is running. There are | ||
| 251 | two modes available: | ||
| 252 | |||
| 253 | NAME MEANING | ||
| 254 | ===== ========================================== | ||
| 255 | wthru Data cache is in Write-Through mode | ||
| 256 | wback Data cache is in Write-Back/Copy-Back mode | ||
| 257 | |||
| 258 | To read the cache mode: | ||
| 259 | |||
| 260 | # cat /proc/sys/frv/cache-mode | ||
| 261 | wthru | ||
| 262 | |||
| 263 | To change the cache mode: | ||
| 264 | |||
| 265 | # echo wback >/proc/sys/frv/cache-mode | ||
| 266 | # cat /proc/sys/frv/cache-mode | ||
| 267 | wback | ||
| 268 | |||
| 269 | |||
| 270 | (*) MMU Context IDs and Pinning | ||
| 271 | |||
| 272 | On MMU Linux the CPU supports the concept of a context ID in its MMU to | ||
| 273 | make it more efficient (TLB entries are labelled with a context ID to link | ||
| 274 | them to specific tasks). | ||
| 275 | |||
| 276 | Normally once a context ID is allocated, it will remain affixed to a task | ||
| 277 | or CLONE_VM'd group of tasks for as long as it exists. However, since the | ||
| 278 | kernel is capable of supporting more tasks than there are possible ID | ||
| 279 | numbers, the kernel will pass context IDs from one task to another if | ||
| 280 | there are insufficient available. | ||
| 281 | |||
| 282 | The context ID currently in use by a task can be viewed in /proc: | ||
| 283 | |||
| 284 | # grep CXNR /proc/1/status | ||
| 285 | CXNR: 1 | ||
| 286 | |||
| 287 | Note that kernel threads do not have a userspace context, and so will not | ||
| 288 | show a CXNR entry in that file. | ||
| 289 | |||
| 290 | Under some circumstances, however, it is desirable to pin a context ID on | ||
| 291 | a process such that the kernel won't pass it on. This can be done by | ||
| 292 | writing the process ID of the target process to a special file: | ||
| 293 | |||
| 294 | # echo 17 >/proc/sys/frv/pin-cxnr | ||
| 295 | |||
| 296 | Reading from the file will then show the context ID pinned. | ||
| 297 | |||
| 298 | # cat /proc/sys/frv/pin-cxnr | ||
| 299 | 4 | ||
| 300 | |||
| 301 | The context ID will remain pinned as long as any process is using that | ||
| 302 | context, i.e.: when the all the subscribing processes have exited or | ||
| 303 | exec'd; or when an unpinning request happens: | ||
| 304 | |||
| 305 | # echo 0 >/proc/sys/frv/pin-cxnr | ||
| 306 | |||
| 307 | When there isn't a pinned context, the file shows -1: | ||
| 308 | |||
| 309 | # cat /proc/sys/frv/pin-cxnr | ||
| 310 | -1 | ||
diff --git a/Documentation/frv/gdbinit b/Documentation/frv/gdbinit new file mode 100644 index 000000000000..51517b6f307f --- /dev/null +++ b/Documentation/frv/gdbinit | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | set remotebreak 1 | ||
| 2 | |||
| 3 | define _amr | ||
| 4 | |||
| 5 | printf "AMRx DAMR IAMR \n" | ||
| 6 | printf "==== ===================== =====================\n" | ||
| 7 | printf "amr0 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x0].L,__debug_mmu.damr[0x0].P,__debug_mmu.iamr[0x0].L,__debug_mmu.iamr[0x0].P | ||
| 8 | printf "amr1 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x1].L,__debug_mmu.damr[0x1].P,__debug_mmu.iamr[0x1].L,__debug_mmu.iamr[0x1].P | ||
| 9 | printf "amr2 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x2].L,__debug_mmu.damr[0x2].P,__debug_mmu.iamr[0x2].L,__debug_mmu.iamr[0x2].P | ||
| 10 | printf "amr3 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x3].L,__debug_mmu.damr[0x3].P,__debug_mmu.iamr[0x3].L,__debug_mmu.iamr[0x3].P | ||
| 11 | printf "amr4 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x4].L,__debug_mmu.damr[0x4].P,__debug_mmu.iamr[0x4].L,__debug_mmu.iamr[0x4].P | ||
| 12 | printf "amr5 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x5].L,__debug_mmu.damr[0x5].P,__debug_mmu.iamr[0x5].L,__debug_mmu.iamr[0x5].P | ||
| 13 | printf "amr6 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x6].L,__debug_mmu.damr[0x6].P,__debug_mmu.iamr[0x6].L,__debug_mmu.iamr[0x6].P | ||
| 14 | printf "amr7 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x7].L,__debug_mmu.damr[0x7].P,__debug_mmu.iamr[0x7].L,__debug_mmu.iamr[0x7].P | ||
| 15 | |||
| 16 | printf "amr8 : L:%08lx P:%08lx\n",__debug_mmu.damr[0x8].L,__debug_mmu.damr[0x8].P | ||
| 17 | printf "amr9 : L:%08lx P:%08lx\n",__debug_mmu.damr[0x9].L,__debug_mmu.damr[0x9].P | ||
| 18 | printf "amr10: L:%08lx P:%08lx\n",__debug_mmu.damr[0xa].L,__debug_mmu.damr[0xa].P | ||
| 19 | printf "amr11: L:%08lx P:%08lx\n",__debug_mmu.damr[0xb].L,__debug_mmu.damr[0xb].P | ||
| 20 | |||
| 21 | end | ||
| 22 | |||
| 23 | |||
| 24 | define _tlb | ||
| 25 | printf "tlb[0x00]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x0].L,__debug_mmu.tlb[0x0].P,__debug_mmu.tlb[0x40+0x0].L,__debug_mmu.tlb[0x40+0x0].P | ||
| 26 | printf "tlb[0x01]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x1].L,__debug_mmu.tlb[0x1].P,__debug_mmu.tlb[0x40+0x1].L,__debug_mmu.tlb[0x40+0x1].P | ||
| 27 | printf "tlb[0x02]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x2].L,__debug_mmu.tlb[0x2].P,__debug_mmu.tlb[0x40+0x2].L,__debug_mmu.tlb[0x40+0x2].P | ||
| 28 | printf "tlb[0x03]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x3].L,__debug_mmu.tlb[0x3].P,__debug_mmu.tlb[0x40+0x3].L,__debug_mmu.tlb[0x40+0x3].P | ||
| 29 | printf "tlb[0x04]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x4].L,__debug_mmu.tlb[0x4].P,__debug_mmu.tlb[0x40+0x4].L,__debug_mmu.tlb[0x40+0x4].P | ||
| 30 | printf "tlb[0x05]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x5].L,__debug_mmu.tlb[0x5].P,__debug_mmu.tlb[0x40+0x5].L,__debug_mmu.tlb[0x40+0x5].P | ||
| 31 | printf "tlb[0x06]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x6].L,__debug_mmu.tlb[0x6].P,__debug_mmu.tlb[0x40+0x6].L,__debug_mmu.tlb[0x40+0x6].P | ||
| 32 | printf "tlb[0x07]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x7].L,__debug_mmu.tlb[0x7].P,__debug_mmu.tlb[0x40+0x7].L,__debug_mmu.tlb[0x40+0x7].P | ||
| 33 | printf "tlb[0x08]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x8].L,__debug_mmu.tlb[0x8].P,__debug_mmu.tlb[0x40+0x8].L,__debug_mmu.tlb[0x40+0x8].P | ||
| 34 | printf "tlb[0x09]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x9].L,__debug_mmu.tlb[0x9].P,__debug_mmu.tlb[0x40+0x9].L,__debug_mmu.tlb[0x40+0x9].P | ||
| 35 | printf "tlb[0x0a]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0xa].L,__debug_mmu.tlb[0xa].P,__debug_mmu.tlb[0x40+0xa].L,__debug_mmu.tlb[0x40+0xa].P | ||
| 36 | printf "tlb[0x0b]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0xb].L,__debug_mmu.tlb[0xb].P,__debug_mmu.tlb[0x40+0xb].L,__debug_mmu.tlb[0x40+0xb].P | ||
| 37 | printf "tlb[0x0c]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0xc].L,__debug_mmu.tlb[0xc].P,__debug_mmu.tlb[0x40+0xc].L,__debug_mmu.tlb[0x40+0xc].P | ||
| 38 | printf "tlb[0x0d]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0xd].L,__debug_mmu.tlb[0xd].P,__debug_mmu.tlb[0x40+0xd].L,__debug_mmu.tlb[0x40+0xd].P | ||
| 39 | printf "tlb[0x0e]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0xe].L,__debug_mmu.tlb[0xe].P,__debug_mmu.tlb[0x40+0xe].L,__debug_mmu.tlb[0x40+0xe].P | ||
| 40 | printf "tlb[0x0f]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0xf].L,__debug_mmu.tlb[0xf].P,__debug_mmu.tlb[0x40+0xf].L,__debug_mmu.tlb[0x40+0xf].P | ||
| 41 | printf "tlb[0x10]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x10].L,__debug_mmu.tlb[0x10].P,__debug_mmu.tlb[0x40+0x10].L,__debug_mmu.tlb[0x40+0x10].P | ||
| 42 | printf "tlb[0x11]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x11].L,__debug_mmu.tlb[0x11].P,__debug_mmu.tlb[0x40+0x11].L,__debug_mmu.tlb[0x40+0x11].P | ||
| 43 | printf "tlb[0x12]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x12].L,__debug_mmu.tlb[0x12].P,__debug_mmu.tlb[0x40+0x12].L,__debug_mmu.tlb[0x40+0x12].P | ||
| 44 | printf "tlb[0x13]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x13].L,__debug_mmu.tlb[0x13].P,__debug_mmu.tlb[0x40+0x13].L,__debug_mmu.tlb[0x40+0x13].P | ||
| 45 | printf "tlb[0x14]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x14].L,__debug_mmu.tlb[0x14].P,__debug_mmu.tlb[0x40+0x14].L,__debug_mmu.tlb[0x40+0x14].P | ||
| 46 | printf "tlb[0x15]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x15].L,__debug_mmu.tlb[0x15].P,__debug_mmu.tlb[0x40+0x15].L,__debug_mmu.tlb[0x40+0x15].P | ||
| 47 | printf "tlb[0x16]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x16].L,__debug_mmu.tlb[0x16].P,__debug_mmu.tlb[0x40+0x16].L,__debug_mmu.tlb[0x40+0x16].P | ||
| 48 | printf "tlb[0x17]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x17].L,__debug_mmu.tlb[0x17].P,__debug_mmu.tlb[0x40+0x17].L,__debug_mmu.tlb[0x40+0x17].P | ||
| 49 | printf "tlb[0x18]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x18].L,__debug_mmu.tlb[0x18].P,__debug_mmu.tlb[0x40+0x18].L,__debug_mmu.tlb[0x40+0x18].P | ||
| 50 | printf "tlb[0x19]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x19].L,__debug_mmu.tlb[0x19].P,__debug_mmu.tlb[0x40+0x19].L,__debug_mmu.tlb[0x40+0x19].P | ||
| 51 | printf "tlb[0x1a]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x1a].L,__debug_mmu.tlb[0x1a].P,__debug_mmu.tlb[0x40+0x1a].L,__debug_mmu.tlb[0x40+0x1a].P | ||
| 52 | printf "tlb[0x1b]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x1b].L,__debug_mmu.tlb[0x1b].P,__debug_mmu.tlb[0x40+0x1b].L,__debug_mmu.tlb[0x40+0x1b].P | ||
| 53 | printf "tlb[0x1c]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x1c].L,__debug_mmu.tlb[0x1c].P,__debug_mmu.tlb[0x40+0x1c].L,__debug_mmu.tlb[0x40+0x1c].P | ||
| 54 | printf "tlb[0x1d]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x1d].L,__debug_mmu.tlb[0x1d].P,__debug_mmu.tlb[0x40+0x1d].L,__debug_mmu.tlb[0x40+0x1d].P | ||
| 55 | printf "tlb[0x1e]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x1e].L,__debug_mmu.tlb[0x1e].P,__debug_mmu.tlb[0x40+0x1e].L,__debug_mmu.tlb[0x40+0x1e].P | ||
| 56 | printf "tlb[0x1f]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x1f].L,__debug_mmu.tlb[0x1f].P,__debug_mmu.tlb[0x40+0x1f].L,__debug_mmu.tlb[0x40+0x1f].P | ||
| 57 | printf "tlb[0x20]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x20].L,__debug_mmu.tlb[0x20].P,__debug_mmu.tlb[0x40+0x20].L,__debug_mmu.tlb[0x40+0x20].P | ||
| 58 | printf "tlb[0x21]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x21].L,__debug_mmu.tlb[0x21].P,__debug_mmu.tlb[0x40+0x21].L,__debug_mmu.tlb[0x40+0x21].P | ||
| 59 | printf "tlb[0x22]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x22].L,__debug_mmu.tlb[0x22].P,__debug_mmu.tlb[0x40+0x22].L,__debug_mmu.tlb[0x40+0x22].P | ||
| 60 | printf "tlb[0x23]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x23].L,__debug_mmu.tlb[0x23].P,__debug_mmu.tlb[0x40+0x23].L,__debug_mmu.tlb[0x40+0x23].P | ||
| 61 | printf "tlb[0x24]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x24].L,__debug_mmu.tlb[0x24].P,__debug_mmu.tlb[0x40+0x24].L,__debug_mmu.tlb[0x40+0x24].P | ||
| 62 | printf "tlb[0x25]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x25].L,__debug_mmu.tlb[0x25].P,__debug_mmu.tlb[0x40+0x25].L,__debug_mmu.tlb[0x40+0x25].P | ||
| 63 | printf "tlb[0x26]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x26].L,__debug_mmu.tlb[0x26].P,__debug_mmu.tlb[0x40+0x26].L,__debug_mmu.tlb[0x40+0x26].P | ||
| 64 | printf "tlb[0x27]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x27].L,__debug_mmu.tlb[0x27].P,__debug_mmu.tlb[0x40+0x27].L,__debug_mmu.tlb[0x40+0x27].P | ||
| 65 | printf "tlb[0x28]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x28].L,__debug_mmu.tlb[0x28].P,__debug_mmu.tlb[0x40+0x28].L,__debug_mmu.tlb[0x40+0x28].P | ||
| 66 | printf "tlb[0x29]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x29].L,__debug_mmu.tlb[0x29].P,__debug_mmu.tlb[0x40+0x29].L,__debug_mmu.tlb[0x40+0x29].P | ||
| 67 | printf "tlb[0x2a]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x2a].L,__debug_mmu.tlb[0x2a].P,__debug_mmu.tlb[0x40+0x2a].L,__debug_mmu.tlb[0x40+0x2a].P | ||
| 68 | printf "tlb[0x2b]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x2b].L,__debug_mmu.tlb[0x2b].P,__debug_mmu.tlb[0x40+0x2b].L,__debug_mmu.tlb[0x40+0x2b].P | ||
| 69 | printf "tlb[0x2c]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x2c].L,__debug_mmu.tlb[0x2c].P,__debug_mmu.tlb[0x40+0x2c].L,__debug_mmu.tlb[0x40+0x2c].P | ||
| 70 | printf "tlb[0x2d]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x2d].L,__debug_mmu.tlb[0x2d].P,__debug_mmu.tlb[0x40+0x2d].L,__debug_mmu.tlb[0x40+0x2d].P | ||
| 71 | printf "tlb[0x2e]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x2e].L,__debug_mmu.tlb[0x2e].P,__debug_mmu.tlb[0x40+0x2e].L,__debug_mmu.tlb[0x40+0x2e].P | ||
| 72 | printf "tlb[0x2f]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x2f].L,__debug_mmu.tlb[0x2f].P,__debug_mmu.tlb[0x40+0x2f].L,__debug_mmu.tlb[0x40+0x2f].P | ||
| 73 | printf "tlb[0x30]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x30].L,__debug_mmu.tlb[0x30].P,__debug_mmu.tlb[0x40+0x30].L,__debug_mmu.tlb[0x40+0x30].P | ||
| 74 | printf "tlb[0x31]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x31].L,__debug_mmu.tlb[0x31].P,__debug_mmu.tlb[0x40+0x31].L,__debug_mmu.tlb[0x40+0x31].P | ||
| 75 | printf "tlb[0x32]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x32].L,__debug_mmu.tlb[0x32].P,__debug_mmu.tlb[0x40+0x32].L,__debug_mmu.tlb[0x40+0x32].P | ||
| 76 | printf "tlb[0x33]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x33].L,__debug_mmu.tlb[0x33].P,__debug_mmu.tlb[0x40+0x33].L,__debug_mmu.tlb[0x40+0x33].P | ||
| 77 | printf "tlb[0x34]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x34].L,__debug_mmu.tlb[0x34].P,__debug_mmu.tlb[0x40+0x34].L,__debug_mmu.tlb[0x40+0x34].P | ||
| 78 | printf "tlb[0x35]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x35].L,__debug_mmu.tlb[0x35].P,__debug_mmu.tlb[0x40+0x35].L,__debug_mmu.tlb[0x40+0x35].P | ||
| 79 | printf "tlb[0x36]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x36].L,__debug_mmu.tlb[0x36].P,__debug_mmu.tlb[0x40+0x36].L,__debug_mmu.tlb[0x40+0x36].P | ||
| 80 | printf "tlb[0x37]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x37].L,__debug_mmu.tlb[0x37].P,__debug_mmu.tlb[0x40+0x37].L,__debug_mmu.tlb[0x40+0x37].P | ||
| 81 | printf "tlb[0x38]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x38].L,__debug_mmu.tlb[0x38].P,__debug_mmu.tlb[0x40+0x38].L,__debug_mmu.tlb[0x40+0x38].P | ||
| 82 | printf "tlb[0x39]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x39].L,__debug_mmu.tlb[0x39].P,__debug_mmu.tlb[0x40+0x39].L,__debug_mmu.tlb[0x40+0x39].P | ||
| 83 | printf "tlb[0x3a]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x3a].L,__debug_mmu.tlb[0x3a].P,__debug_mmu.tlb[0x40+0x3a].L,__debug_mmu.tlb[0x40+0x3a].P | ||
| 84 | printf "tlb[0x3b]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x3b].L,__debug_mmu.tlb[0x3b].P,__debug_mmu.tlb[0x40+0x3b].L,__debug_mmu.tlb[0x40+0x3b].P | ||
| 85 | printf "tlb[0x3c]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x3c].L,__debug_mmu.tlb[0x3c].P,__debug_mmu.tlb[0x40+0x3c].L,__debug_mmu.tlb[0x40+0x3c].P | ||
| 86 | printf "tlb[0x3d]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x3d].L,__debug_mmu.tlb[0x3d].P,__debug_mmu.tlb[0x40+0x3d].L,__debug_mmu.tlb[0x40+0x3d].P | ||
| 87 | printf "tlb[0x3e]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x3e].L,__debug_mmu.tlb[0x3e].P,__debug_mmu.tlb[0x40+0x3e].L,__debug_mmu.tlb[0x40+0x3e].P | ||
| 88 | printf "tlb[0x3f]: %08lx %08lx %08lx %08lx\n",__debug_mmu.tlb[0x3f].L,__debug_mmu.tlb[0x3f].P,__debug_mmu.tlb[0x40+0x3f].L,__debug_mmu.tlb[0x40+0x3f].P | ||
| 89 | end | ||
| 90 | |||
| 91 | |||
| 92 | define _pgd | ||
| 93 | p (pgd_t[0x40])*(pgd_t*)(__debug_mmu.damr[0x3].L) | ||
| 94 | end | ||
| 95 | |||
| 96 | define _ptd_i | ||
| 97 | p (pte_t[0x1000])*(pte_t*)(__debug_mmu.damr[0x4].L) | ||
| 98 | end | ||
| 99 | |||
| 100 | define _ptd_d | ||
| 101 | p (pte_t[0x1000])*(pte_t*)(__debug_mmu.damr[0x5].L) | ||
| 102 | end | ||
diff --git a/Documentation/frv/gdbstub.txt b/Documentation/frv/gdbstub.txt new file mode 100644 index 000000000000..b92bfd902a4e --- /dev/null +++ b/Documentation/frv/gdbstub.txt | |||
| @@ -0,0 +1,130 @@ | |||
| 1 | ==================== | ||
| 2 | DEBUGGING FR-V LINUX | ||
| 3 | ==================== | ||
| 4 | |||
| 5 | |||
| 6 | The kernel contains a GDB stub that talks GDB remote protocol across a serial | ||
| 7 | port. This permits GDB to single step through the kernel, set breakpoints and | ||
| 8 | trap exceptions that happen in kernel space and interrupt execution. It also | ||
| 9 | permits the NMI interrupt button or serial port events to jump the kernel into | ||
| 10 | the debugger. | ||
| 11 | |||
| 12 | On the CPUs that have on-chip UARTs (FR400, FR403, FR405, FR555), the | ||
| 13 | GDB stub hijacks a serial port for its own purposes, and makes it | ||
| 14 | generate level 15 interrupts (NMI). The kernel proper cannot see the serial | ||
| 15 | port in question under these conditions. | ||
| 16 | |||
| 17 | On the MB93091-VDK CPU boards, the GDB stub uses UART1, which would otherwise | ||
| 18 | be /dev/ttyS1. On the MB93093-PDK, the GDB stub uses UART0. Therefore, on the | ||
| 19 | PDK there is no externally accessible serial port and the serial port to | ||
| 20 | which the touch screen is attached becomes /dev/ttyS0. | ||
| 21 | |||
| 22 | Note that the GDB stub runs entirely within CPU debug mode, and so should not | ||
| 23 | incur any exceptions or interrupts whilst it is active. In particular, note | ||
| 24 | that the clock will lose time since it is implemented in software. | ||
| 25 | |||
| 26 | |||
| 27 | ================== | ||
| 28 | KERNEL PREPARATION | ||
| 29 | ================== | ||
| 30 | |||
| 31 | Firstly, a debuggable kernel must be built. To do this, unpack the kernel tree | ||
| 32 | and copy the configuration that you wish to use to .config. Then reconfigure | ||
| 33 | the following things on the "Kernel Hacking" tab: | ||
| 34 | |||
| 35 | (*) "Include debugging information" | ||
| 36 | |||
| 37 | Set this to "Y". This causes all C and Assembly files to be compiled | ||
| 38 | to include debugging information. | ||
| 39 | |||
| 40 | (*) "In-kernel GDB stub" | ||
| 41 | |||
| 42 | Set this to "Y". This causes the GDB stub to be compiled into the | ||
| 43 | kernel. | ||
| 44 | |||
| 45 | (*) "Immediate activation" | ||
| 46 | |||
| 47 | Set this to "Y" if you want the GDB stub to activate as soon as possible | ||
| 48 | and wait for GDB to connect. This allows you to start tracing right from | ||
| 49 | the beginning of start_kernel() in init/main.c. | ||
| 50 | |||
| 51 | (*) "Console through GDB stub" | ||
| 52 | |||
| 53 | Set this to "Y" if you wish to be able to use "console=gdb0" on the | ||
| 54 | command line. That tells the kernel to pass system console messages to | ||
| 55 | GDB (which then prints them on its standard output). This is useful when | ||
| 56 | debugging the serial drivers that'd otherwise be used to pass console | ||
| 57 | messages to the outside world. | ||
| 58 | |||
| 59 | Then build as usual, download to the board and execute. Note that if | ||
| 60 | "Immediate activation" was selected, then the kernel will wait for GDB to | ||
| 61 | attach. If not, then the kernel will boot immediately and GDB will have to | ||
| 62 | interrupt it or wait for an exception to occur before doing anything with | ||
| 63 | the kernel. | ||
| 64 | |||
| 65 | |||
| 66 | ========================= | ||
| 67 | KERNEL DEBUGGING WITH GDB | ||
| 68 | ========================= | ||
| 69 | |||
| 70 | Set the serial port on the computer that's going to run GDB to the appropriate | ||
| 71 | baud rate. Assuming the board's debug port is connected to ttyS0/COM1 on the | ||
| 72 | computer doing the debugging: | ||
| 73 | |||
| 74 | stty -F /dev/ttyS0 115200 | ||
| 75 | |||
| 76 | Then start GDB in the base of the kernel tree: | ||
| 77 | |||
| 78 | frv-uclinux-gdb linux [uClinux] | ||
| 79 | |||
| 80 | Or: | ||
| 81 | |||
| 82 | frv-uclinux-gdb vmlinux [MMU linux] | ||
| 83 | |||
| 84 | When the prompt appears: | ||
| 85 | |||
| 86 | GNU gdb frv-031024 | ||
| 87 | Copyright 2003 Free Software Foundation, Inc. | ||
| 88 | GDB is free software, covered by the GNU General Public License, and you are | ||
| 89 | welcome to change it and/or distribute copies of it under certain conditions. | ||
| 90 | Type "show copying" to see the conditions. | ||
| 91 | There is absolutely no warranty for GDB. Type "show warranty" for details. | ||
| 92 | This GDB was configured as "--host=i686-pc-linux-gnu --target=frv-uclinux"... | ||
| 93 | (gdb) | ||
| 94 | |||
| 95 | Attach to the board like this: | ||
| 96 | |||
| 97 | (gdb) target remote /dev/ttyS0 | ||
| 98 | Remote debugging using /dev/ttyS0 | ||
| 99 | start_kernel () at init/main.c:395 | ||
| 100 | (gdb) | ||
| 101 | |||
| 102 | This should show the appropriate lines from the source too. The kernel can | ||
| 103 | then be debugged almost as if it's any other program. | ||
| 104 | |||
| 105 | |||
| 106 | =============================== | ||
| 107 | INTERRUPTING THE RUNNING KERNEL | ||
| 108 | =============================== | ||
| 109 | |||
| 110 | The kernel can be interrupted whilst it is running, causing a jump back to the | ||
| 111 | GDB stub and the debugger: | ||
| 112 | |||
| 113 | (*) Pressing Ctrl-C in GDB. This will cause GDB to try and interrupt the | ||
| 114 | kernel by sending an RS232 BREAK over the serial line to the GDB | ||
| 115 | stub. This will (mostly) immediately interrupt the kernel and return it | ||
| 116 | to the debugger. | ||
| 117 | |||
| 118 | (*) Pressing the NMI button on the board will also cause a jump into the | ||
| 119 | debugger. | ||
| 120 | |||
| 121 | (*) Setting a software breakpoint. This sets a break instruction at the | ||
| 122 | desired location which the GDB stub then traps the exception for. | ||
| 123 | |||
| 124 | (*) Setting a hardware breakpoint. The GDB stub is capable of using the IBAR | ||
| 125 | and DBAR registers to assist debugging. | ||
| 126 | |||
| 127 | Furthermore, the GDB stub will intercept a number of exceptions automatically | ||
| 128 | if they are caused by kernel execution. It will also intercept BUG() macro | ||
| 129 | invocation. | ||
| 130 | |||
diff --git a/Documentation/frv/kernel-ABI.txt b/Documentation/frv/kernel-ABI.txt new file mode 100644 index 000000000000..aaa1cec86f0b --- /dev/null +++ b/Documentation/frv/kernel-ABI.txt | |||
| @@ -0,0 +1,262 @@ | |||
| 1 | ================================= | ||
| 2 | INTERNAL KERNEL ABI FOR FR-V ARCH | ||
| 3 | ================================= | ||
| 4 | |||
| 5 | The internal FRV kernel ABI is not quite the same as the userspace ABI. A | ||
| 6 | number of the registers are used for special purposed, and the ABI is not | ||
| 7 | consistent between modules vs core, and MMU vs no-MMU. | ||
| 8 | |||
| 9 | This partly stems from the fact that FRV CPUs do not have a separate | ||
| 10 | supervisor stack pointer, and most of them do not have any scratch | ||
| 11 | registers, thus requiring at least one general purpose register to be | ||
| 12 | clobbered in such an event. Also, within the kernel core, it is possible to | ||
| 13 | simply jump or call directly between functions using a relative offset. | ||
| 14 | This cannot be extended to modules for the displacement is likely to be too | ||
| 15 | far. Thus in modules the address of a function to call must be calculated | ||
| 16 | in a register and then used, requiring two extra instructions. | ||
| 17 | |||
| 18 | This document has the following sections: | ||
| 19 | |||
| 20 | (*) System call register ABI | ||
| 21 | (*) CPU operating modes | ||
| 22 | (*) Internal kernel-mode register ABI | ||
| 23 | (*) Internal debug-mode register ABI | ||
| 24 | (*) Virtual interrupt handling | ||
| 25 | |||
| 26 | |||
| 27 | ======================== | ||
| 28 | SYSTEM CALL REGISTER ABI | ||
| 29 | ======================== | ||
| 30 | |||
| 31 | When a system call is made, the following registers are effective: | ||
| 32 | |||
| 33 | REGISTERS CALL RETURN | ||
| 34 | =============== ======================= ======================= | ||
| 35 | GR7 System call number Preserved | ||
| 36 | GR8 Syscall arg #1 Return value | ||
| 37 | GR9-GR13 Syscall arg #2-6 Preserved | ||
| 38 | |||
| 39 | |||
| 40 | =================== | ||
| 41 | CPU OPERATING MODES | ||
| 42 | =================== | ||
| 43 | |||
| 44 | The FR-V CPU has three basic operating modes. In order of increasing | ||
| 45 | capability: | ||
| 46 | |||
| 47 | (1) User mode. | ||
| 48 | |||
| 49 | Basic userspace running mode. | ||
| 50 | |||
| 51 | (2) Kernel mode. | ||
| 52 | |||
| 53 | Normal kernel mode. There are many additional control registers | ||
| 54 | available that may be accessed in this mode, in addition to all the | ||
| 55 | stuff available to user mode. This has two submodes: | ||
| 56 | |||
| 57 | (a) Exceptions enabled (PSR.T == 1). | ||
| 58 | |||
| 59 | Exceptions will invoke the appropriate normal kernel mode | ||
| 60 | handler. On entry to the handler, the PSR.T bit will be cleared. | ||
| 61 | |||
| 62 | (b) Exceptions disabled (PSR.T == 0). | ||
| 63 | |||
| 64 | No exceptions or interrupts may happen. Any mandatory exceptions | ||
| 65 | will cause the CPU to halt unless the CPU is told to jump into | ||
| 66 | debug mode instead. | ||
| 67 | |||
| 68 | (3) Debug mode. | ||
| 69 | |||
| 70 | No exceptions may happen in this mode. Memory protection and | ||
| 71 | management exceptions will be flagged for later consideration, but | ||
| 72 | the exception handler won't be invoked. Debugging traps such as | ||
| 73 | hardware breakpoints and watchpoints will be ignored. This mode is | ||
| 74 | entered only by debugging events obtained from the other two modes. | ||
| 75 | |||
| 76 | All kernel mode registers may be accessed, plus a few extra debugging | ||
| 77 | specific registers. | ||
| 78 | |||
| 79 | |||
| 80 | ================================= | ||
| 81 | INTERNAL KERNEL-MODE REGISTER ABI | ||
| 82 | ================================= | ||
| 83 | |||
| 84 | There are a number of permanent register assignments that are set up by | ||
| 85 | entry.S in the exception prologue. Note that there is a complete set of | ||
| 86 | exception prologues for each of user->kernel transition and kernel->kernel | ||
| 87 | transition. There are also user->debug and kernel->debug mode transition | ||
| 88 | prologues. | ||
| 89 | |||
| 90 | |||
| 91 | REGISTER FLAVOUR USE | ||
| 92 | =============== ======= ============================================== | ||
| 93 | GR1 Supervisor stack pointer | ||
| 94 | GR15 Current thread info pointer | ||
| 95 | GR16 GP-Rel base register for small data | ||
| 96 | GR28 Current exception frame pointer (__frame) | ||
| 97 | GR29 Current task pointer (current) | ||
| 98 | GR30 Destroyed by kernel mode entry | ||
| 99 | GR31 NOMMU Destroyed by debug mode entry | ||
| 100 | GR31 MMU Destroyed by TLB miss kernel mode entry | ||
| 101 | CCR.ICC2 Virtual interrupt disablement tracking | ||
| 102 | CCCR.CC3 Cleared by exception prologue | ||
| 103 | (atomic op emulation) | ||
| 104 | SCR0 MMU See mmu-layout.txt. | ||
| 105 | SCR1 MMU See mmu-layout.txt. | ||
| 106 | SCR2 MMU Save for EAR0 (destroyed by icache insns | ||
| 107 | in debug mode) | ||
| 108 | SCR3 MMU Save for GR31 during debug exceptions | ||
| 109 | DAMR/IAMR NOMMU Fixed memory protection layout. | ||
| 110 | DAMR/IAMR MMU See mmu-layout.txt. | ||
| 111 | |||
| 112 | |||
| 113 | Certain registers are also used or modified across function calls: | ||
| 114 | |||
| 115 | REGISTER CALL RETURN | ||
| 116 | =============== =============================== ====================== | ||
| 117 | GR0 Fixed Zero - | ||
| 118 | GR2 Function call frame pointer | ||
| 119 | GR3 Special Preserved | ||
| 120 | GR3-GR7 - Clobbered | ||
| 121 | GR8 Function call arg #1 Return value | ||
| 122 | (or clobbered) | ||
| 123 | GR9 Function call arg #2 Return value MSW | ||
| 124 | (or clobbered) | ||
| 125 | GR10-GR13 Function call arg #3-#6 Clobbered | ||
| 126 | GR14 - Clobbered | ||
| 127 | GR15-GR16 Special Preserved | ||
| 128 | GR17-GR27 - Preserved | ||
| 129 | GR28-GR31 Special Only accessed | ||
| 130 | explicitly | ||
| 131 | LR Return address after CALL Clobbered | ||
| 132 | CCR/CCCR - Mostly Clobbered | ||
| 133 | |||
| 134 | |||
| 135 | ================================ | ||
| 136 | INTERNAL DEBUG-MODE REGISTER ABI | ||
| 137 | ================================ | ||
| 138 | |||
| 139 | This is the same as the kernel-mode register ABI for functions calls. The | ||
| 140 | difference is that in debug-mode there's a different stack and a different | ||
| 141 | exception frame. Almost all the global registers from kernel-mode | ||
| 142 | (including the stack pointer) may be changed. | ||
| 143 | |||
| 144 | REGISTER FLAVOUR USE | ||
| 145 | =============== ======= ============================================== | ||
| 146 | GR1 Debug stack pointer | ||
| 147 | GR16 GP-Rel base register for small data | ||
| 148 | GR31 Current debug exception frame pointer | ||
| 149 | (__debug_frame) | ||
| 150 | SCR3 MMU Saved value of GR31 | ||
| 151 | |||
| 152 | |||
| 153 | Note that debug mode is able to interfere with the kernel's emulated atomic | ||
| 154 | ops, so it must be exceedingly careful not to do any that would interact | ||
| 155 | with the main kernel in this regard. Hence the debug mode code (gdbstub) is | ||
| 156 | almost completely self-contained. The only external code used is the | ||
| 157 | sprintf family of functions. | ||
| 158 | |||
| 159 | Furthermore, break.S is so complicated because single-step mode does not | ||
| 160 | switch off on entry to an exception. That means unless manually disabled, | ||
| 161 | single-stepping will blithely go on stepping into things like interrupts. | ||
| 162 | See gdbstub.txt for more information. | ||
| 163 | |||
| 164 | |||
| 165 | ========================== | ||
| 166 | VIRTUAL INTERRUPT HANDLING | ||
| 167 | ========================== | ||
| 168 | |||
| 169 | Because accesses to the PSR is so slow, and to disable interrupts we have | ||
| 170 | to access it twice (once to read and once to write), we don't actually | ||
| 171 | disable interrupts at all if we don't have to. What we do instead is use | ||
| 172 | the ICC2 condition code flags to note virtual disablement, such that if we | ||
| 173 | then do take an interrupt, we note the flag, really disable interrupts, set | ||
| 174 | another flag and resume execution at the point the interrupt happened. | ||
| 175 | Setting condition flags as a side effect of an arithmetic or logical | ||
| 176 | instruction is really fast. This use of the ICC2 only occurs within the | ||
| 177 | kernel - it does not affect userspace. | ||
| 178 | |||
| 179 | The flags we use are: | ||
| 180 | |||
| 181 | (*) CCR.ICC2.Z [Zero flag] | ||
| 182 | |||
| 183 | Set to virtually disable interrupts, clear when interrupts are | ||
| 184 | virtually enabled. Can be modified by logical instructions without | ||
| 185 | affecting the Carry flag. | ||
| 186 | |||
| 187 | (*) CCR.ICC2.C [Carry flag] | ||
| 188 | |||
| 189 | Clear to indicate hardware interrupts are really disabled, set otherwise. | ||
| 190 | |||
| 191 | |||
| 192 | What happens is this: | ||
| 193 | |||
| 194 | (1) Normal kernel-mode operation. | ||
| 195 | |||
| 196 | ICC2.Z is 0, ICC2.C is 1. | ||
| 197 | |||
| 198 | (2) An interrupt occurs. The exception prologue examines ICC2.Z and | ||
| 199 | determines that nothing needs doing. This is done simply with an | ||
| 200 | unlikely BEQ instruction. | ||
| 201 | |||
| 202 | (3) The interrupts are disabled (local_irq_disable) | ||
| 203 | |||
| 204 | ICC2.Z is set to 1. | ||
| 205 | |||
| 206 | (4) If interrupts were then re-enabled (local_irq_enable): | ||
| 207 | |||
| 208 | ICC2.Z would be set to 0. | ||
| 209 | |||
| 210 | A TIHI #2 instruction (trap #2 if condition HI - Z==0 && C==0) would | ||
| 211 | be used to trap if interrupts were now virtually enabled, but | ||
| 212 | physically disabled - which they're not, so the trap isn't taken. The | ||
| 213 | kernel would then be back to state (1). | ||
| 214 | |||
| 215 | (5) An interrupt occurs. The exception prologue examines ICC2.Z and | ||
| 216 | determines that the interrupt shouldn't actually have happened. It | ||
| 217 | jumps aside, and there disabled interrupts by setting PSR.PIL to 14 | ||
| 218 | and then it clears ICC2.C. | ||
| 219 | |||
| 220 | (6) If interrupts were then saved and disabled again (local_irq_save): | ||
| 221 | |||
| 222 | ICC2.Z would be shifted into the save variable and masked off | ||
| 223 | (giving a 1). | ||
| 224 | |||
| 225 | ICC2.Z would then be set to 1 (thus unchanged), and ICC2.C would be | ||
| 226 | unaffected (ie: 0). | ||
| 227 | |||
| 228 | (7) If interrupts were then restored from state (6) (local_irq_restore): | ||
| 229 | |||
| 230 | ICC2.Z would be set to indicate the result of XOR'ing the saved | ||
| 231 | value (ie: 1) with 1, which gives a result of 0 - thus leaving | ||
| 232 | ICC2.Z set. | ||
| 233 | |||
| 234 | ICC2.C would remain unaffected (ie: 0). | ||
| 235 | |||
| 236 | A TIHI #2 instruction would be used to again assay the current state, | ||
| 237 | but this would do nothing as Z==1. | ||
| 238 | |||
| 239 | (8) If interrupts were then enabled (local_irq_enable): | ||
| 240 | |||
| 241 | ICC2.Z would be cleared. ICC2.C would be left unaffected. Both | ||
| 242 | flags would now be 0. | ||
| 243 | |||
| 244 | A TIHI #2 instruction again issued to assay the current state would | ||
| 245 | then trap as both Z==0 [interrupts virtually enabled] and C==0 | ||
| 246 | [interrupts really disabled] would then be true. | ||
| 247 | |||
| 248 | (9) The trap #2 handler would simply enable hardware interrupts | ||
| 249 | (set PSR.PIL to 0), set ICC2.C to 1 and return. | ||
| 250 | |||
| 251 | (10) Immediately upon returning, the pending interrupt would be taken. | ||
| 252 | |||
| 253 | (11) The interrupt handler would take the path of actually processing the | ||
| 254 | interrupt (ICC2.Z is clear, BEQ fails as per step (2)). | ||
| 255 | |||
| 256 | (12) The interrupt handler would then set ICC2.C to 1 since hardware | ||
| 257 | interrupts are definitely enabled - or else the kernel wouldn't be here. | ||
| 258 | |||
| 259 | (13) On return from the interrupt handler, things would be back to state (1). | ||
| 260 | |||
| 261 | This trap (#2) is only available in kernel mode. In user mode it will | ||
| 262 | result in SIGILL. | ||
diff --git a/Documentation/frv/mmu-layout.txt b/Documentation/frv/mmu-layout.txt new file mode 100644 index 000000000000..db10250df6be --- /dev/null +++ b/Documentation/frv/mmu-layout.txt | |||
| @@ -0,0 +1,306 @@ | |||
| 1 | ================================= | ||
| 2 | FR451 MMU LINUX MEMORY MANAGEMENT | ||
| 3 | ================================= | ||
| 4 | |||
| 5 | ============ | ||
| 6 | MMU HARDWARE | ||
| 7 | ============ | ||
| 8 | |||
| 9 | FR451 MMU Linux puts the MMU into EDAT mode whilst running. This means that it uses both the SAT | ||
| 10 | registers and the DAT TLB to perform address translation. | ||
| 11 | |||
| 12 | There are 8 IAMLR/IAMPR register pairs and 16 DAMLR/DAMPR register pairs for SAT mode. | ||
| 13 | |||
| 14 | In DAT mode, there is also a TLB organised in cache format as 64 lines x 2 ways. Each line spans a | ||
| 15 | 16KB range of addresses, but can match a larger region. | ||
| 16 | |||
| 17 | |||
| 18 | =========================== | ||
| 19 | MEMORY MANAGEMENT REGISTERS | ||
| 20 | =========================== | ||
| 21 | |||
| 22 | Certain control registers are used by the kernel memory management routines: | ||
| 23 | |||
| 24 | REGISTERS USAGE | ||
| 25 | ====================== ================================================== | ||
| 26 | IAMR0, DAMR0 Kernel image and data mappings | ||
| 27 | IAMR1, DAMR1 First-chance TLB lookup mapping | ||
| 28 | DAMR2 Page attachment for cache flush by page | ||
| 29 | DAMR3 Current PGD mapping | ||
| 30 | SCR0, DAMR4 Instruction TLB PGE/PTD cache | ||
| 31 | SCR1, DAMR5 Data TLB PGE/PTD cache | ||
| 32 | DAMR6-10 kmap_atomic() mappings | ||
| 33 | DAMR11 I/O mapping | ||
| 34 | CXNR mm_struct context ID | ||
| 35 | TTBR Page directory (PGD) pointer (physical address) | ||
| 36 | |||
| 37 | |||
| 38 | ===================== | ||
| 39 | GENERAL MEMORY LAYOUT | ||
| 40 | ===================== | ||
| 41 | |||
| 42 | The physical memory layout is as follows: | ||
| 43 | |||
| 44 | PHYSICAL ADDRESS CONTROLLER DEVICE | ||
| 45 | =================== ============== ======================================= | ||
| 46 | 00000000 - BFFFFFFF SDRAM SDRAM area | ||
| 47 | E0000000 - EFFFFFFF L-BUS CS2# VDK SLBUS/PCI window | ||
| 48 | F0000000 - F0FFFFFF L-BUS CS5# MB93493 CSC area (DAV daughter board) | ||
| 49 | F1000000 - F1FFFFFF L-BUS CS7# (CB70 CPU-card PCMCIA port I/O space) | ||
| 50 | FC000000 - FC0FFFFF L-BUS CS1# VDK MB86943 config space | ||
| 51 | FC100000 - FC1FFFFF L-BUS CS6# DM9000 NIC I/O space | ||
| 52 | FC200000 - FC2FFFFF L-BUS CS3# MB93493 CSR area (DAV daughter board) | ||
| 53 | FD000000 - FDFFFFFF L-BUS CS4# (CB70 CPU-card extra flash space) | ||
| 54 | FE000000 - FEFFFFFF Internal CPU peripherals | ||
| 55 | FF000000 - FF1FFFFF L-BUS CS0# Flash 1 | ||
| 56 | FF200000 - FF3FFFFF L-BUS CS0# Flash 2 | ||
| 57 | FFC00000 - FFC0001F L-BUS CS0# FPGA | ||
| 58 | |||
| 59 | The virtual memory layout is: | ||
| 60 | |||
| 61 | VIRTUAL ADDRESS PHYSICAL TRANSLATOR FLAGS SIZE OCCUPATION | ||
| 62 | ================= ======== ============== ======= ======= =================================== | ||
| 63 | 00004000-BFFFFFFF various TLB,xAMR1 D-N-??V 3GB Userspace | ||
| 64 | C0000000-CFFFFFFF 00000000 xAMPR0 -L-S--V 256MB Kernel image and data | ||
| 65 | D0000000-D7FFFFFF various TLB,xAMR1 D-NS??V 128MB vmalloc area | ||
| 66 | D8000000-DBFFFFFF various TLB,xAMR1 D-NS??V 64MB kmap() area | ||
| 67 | DC000000-DCFFFFFF various TLB 1MB Secondary kmap_atomic() frame | ||
| 68 | DD000000-DD27FFFF various DAMR 160KB Primary kmap_atomic() frame | ||
| 69 | DD040000 DAMR2/IAMR2 -L-S--V page Page cache flush attachment point | ||
| 70 | DD080000 DAMR3 -L-SC-V page Page Directory (PGD) | ||
| 71 | DD0C0000 DAMR4 -L-SC-V page Cached insn TLB Page Table lookup | ||
| 72 | DD100000 DAMR5 -L-SC-V page Cached data TLB Page Table lookup | ||
| 73 | DD140000 DAMR6 -L-S--V page kmap_atomic(KM_BOUNCE_READ) | ||
| 74 | DD180000 DAMR7 -L-S--V page kmap_atomic(KM_SKB_SUNRPC_DATA) | ||
| 75 | DD1C0000 DAMR8 -L-S--V page kmap_atomic(KM_SKB_DATA_SOFTIRQ) | ||
| 76 | DD200000 DAMR9 -L-S--V page kmap_atomic(KM_USER0) | ||
| 77 | DD240000 DAMR10 -L-S--V page kmap_atomic(KM_USER1) | ||
| 78 | E0000000-FFFFFFFF E0000000 DAMR11 -L-SC-V 512MB I/O region | ||
| 79 | |||
| 80 | IAMPR1 and DAMPR1 are used as an extension to the TLB. | ||
| 81 | |||
| 82 | |||
| 83 | ==================== | ||
| 84 | KMAP AND KMAP_ATOMIC | ||
| 85 | ==================== | ||
| 86 | |||
| 87 | To access pages in the page cache (which may not be directly accessible if highmem is available), | ||
| 88 | the kernel calls kmap(), does the access and then calls kunmap(); or it calls kmap_atomic(), does | ||
| 89 | the access and then calls kunmap_atomic(). | ||
| 90 | |||
| 91 | kmap() creates an attachment between an arbitrary inaccessible page and a range of virtual | ||
| 92 | addresses by installing a PTE in a special page table. The kernel can then access this page as it | ||
| 93 | wills. When it's finished, the kernel calls kunmap() to clear the PTE. | ||
| 94 | |||
| 95 | kmap_atomic() does something slightly different. In the interests of speed, it chooses one of two | ||
| 96 | strategies: | ||
| 97 | |||
| 98 | (1) If possible, kmap_atomic() attaches the requested page to one of DAMPR5 through DAMPR10 | ||
| 99 | register pairs; and the matching kunmap_atomic() clears the DAMPR. This makes high memory | ||
| 100 | support really fast as there's no need to flush the TLB or modify the page tables. The DAMLR | ||
| 101 | registers being used for this are preset during boot and don't change over the lifetime of the | ||
| 102 | process. There's a direct mapping between the first few kmap_atomic() types, DAMR number and | ||
| 103 | virtual address slot. | ||
| 104 | |||
| 105 | However, there are more kmap_atomic() types defined than there are DAMR registers available, | ||
| 106 | so we fall back to: | ||
| 107 | |||
| 108 | (2) kmap_atomic() uses a slot in the secondary frame (determined by the type parameter), and then | ||
| 109 | locks an entry in the TLB to translate that slot to the specified page. The number of slots is | ||
| 110 | obviously limited, and their positions are controlled such that each slot is matched by a | ||
| 111 | different line in the TLB. kunmap() ejects the entry from the TLB. | ||
| 112 | |||
| 113 | Note that the first three kmap atomic types are really just declared as placeholders. The DAMPR | ||
| 114 | registers involved are actually modified directly. | ||
| 115 | |||
| 116 | Also note that kmap() itself may sleep, kmap_atomic() may never sleep and both always succeed; | ||
| 117 | furthermore, a driver using kmap() may sleep before calling kunmap(), but may not sleep before | ||
| 118 | calling kunmap_atomic() if it had previously called kmap_atomic(). | ||
| 119 | |||
| 120 | |||
| 121 | =============================== | ||
| 122 | USING MORE THAN 256MB OF MEMORY | ||
| 123 | =============================== | ||
| 124 | |||
| 125 | The kernel cannot access more than 256MB of memory directly. The physical layout, however, permits | ||
| 126 | up to 3GB of SDRAM (possibly 3.25GB) to be made available. By using CONFIG_HIGHMEM, the kernel can | ||
| 127 | allow userspace (by way of page tables) and itself (by way of kmap) to deal with the memory | ||
| 128 | allocation. | ||
| 129 | |||
| 130 | External devices can, of course, still DMA to and from all of the SDRAM, even if the kernel can't | ||
| 131 | see it directly. The kernel translates page references into real addresses for communicating to the | ||
| 132 | devices. | ||
| 133 | |||
| 134 | |||
| 135 | =================== | ||
| 136 | PAGE TABLE TOPOLOGY | ||
| 137 | =================== | ||
| 138 | |||
| 139 | The page tables are arranged in 2-layer format. There is a middle layer (PMD) that would be used in | ||
| 140 | 3-layer format tables but that is folded into the top layer (PGD) and so consumes no extra memory | ||
| 141 | or processing power. | ||
| 142 | |||
| 143 | +------+ PGD PMD | ||
| 144 | | TTBR |--->+-------------------+ | ||
| 145 | +------+ | | : STE | | ||
| 146 | | PGE0 | PME0 : STE | | ||
| 147 | | | : STE | | ||
| 148 | +-------------------+ Page Table | ||
| 149 | | | : STE -------------->+--------+ +0x0000 | ||
| 150 | | PGE1 | PME0 : STE -----------+ | PTE0 | | ||
| 151 | | | : STE -------+ | +--------+ | ||
| 152 | +-------------------+ | | | PTE63 | | ||
| 153 | | | : STE | | +-->+--------+ +0x0100 | ||
| 154 | | PGE2 | PME0 : STE | | | PTE64 | | ||
| 155 | | | : STE | | +--------+ | ||
| 156 | +-------------------+ | | PTE127 | | ||
| 157 | | | : STE | +------>+--------+ +0x0200 | ||
| 158 | | PGE3 | PME0 : STE | | PTE128 | | ||
| 159 | | | : STE | +--------+ | ||
| 160 | +-------------------+ | PTE191 | | ||
| 161 | +--------+ +0x0300 | ||
| 162 | |||
| 163 | Each Page Directory (PGD) is 16KB (page size) in size and is divided into 64 entries (PGEs). Each | ||
| 164 | PGE contains one Page Mid Directory (PMD). | ||
| 165 | |||
| 166 | Each PMD is 256 bytes in size and contains a single entry (PME). Each PME holds 64 FR451 MMU | ||
| 167 | segment table entries of 4 bytes apiece. Each PME "points to" a page table. In practice, each STE | ||
| 168 | points to a subset of the page table, the first to PT+0x0000, the second to PT+0x0100, the third to | ||
| 169 | PT+0x200, and so on. | ||
| 170 | |||
| 171 | Each PGE and PME covers 64MB of the total virtual address space. | ||
| 172 | |||
| 173 | Each Page Table (PTD) is 16KB (page size) in size, and is divided into 4096 entries (PTEs). Each | ||
| 174 | entry can point to one 16KB page. In practice, each Linux page table is subdivided into 64 FR451 | ||
| 175 | MMU page tables. But they are all grouped together to make management easier, in particular rmap | ||
| 176 | support is then trivial. | ||
| 177 | |||
| 178 | Grouping page tables in this fashion makes PGE caching in SCR0/SCR1 more efficient because the | ||
| 179 | coverage of the cached item is greater. | ||
| 180 | |||
| 181 | Page tables for the vmalloc area are allocated at boot time and shared between all mm_structs. | ||
| 182 | |||
| 183 | |||
| 184 | ================= | ||
| 185 | USER SPACE LAYOUT | ||
| 186 | ================= | ||
| 187 | |||
| 188 | For MMU capable Linux, the regions userspace code are allowed to access are kept entirely separate | ||
| 189 | from those dedicated to the kernel: | ||
| 190 | |||
| 191 | VIRTUAL ADDRESS SIZE PURPOSE | ||
| 192 | ================= ===== =================================== | ||
| 193 | 00000000-00003fff 4KB NULL pointer access trap | ||
| 194 | 00004000-01ffffff ~32MB lower mmap space (grows up) | ||
| 195 | 02000000-021fffff 2MB Stack space (grows down from top) | ||
| 196 | 02200000-nnnnnnnn Executable mapping | ||
| 197 | nnnnnnnn- brk space (grows up) | ||
| 198 | -bfffffff upper mmap space (grows down) | ||
| 199 | |||
| 200 | This is so arranged so as to make best use of the 16KB page tables and the way in which PGEs/PMEs | ||
| 201 | are cached by the TLB handler. The lower mmap space is filled first, and then the upper mmap space | ||
| 202 | is filled. | ||
| 203 | |||
| 204 | |||
| 205 | =============================== | ||
| 206 | GDB-STUB MMU DEBUGGING SERVICES | ||
| 207 | =============================== | ||
| 208 | |||
| 209 | The gdb-stub included in this kernel provides a number of services to aid in the debugging of MMU | ||
| 210 | related kernel services: | ||
| 211 | |||
| 212 | (*) Every time the kernel stops, certain state information is dumped into __debug_mmu. This | ||
| 213 | variable is defined in arch/frv/kernel/gdb-stub.c. Note that the gdbinit file in this | ||
| 214 | directory has some useful macros for dealing with this. | ||
| 215 | |||
| 216 | (*) __debug_mmu.tlb[] | ||
| 217 | |||
| 218 | This receives the current TLB contents. This can be viewed with the _tlb GDB macro: | ||
| 219 | |||
| 220 | (gdb) _tlb | ||
| 221 | tlb[0x00]: 01000005 00718203 01000002 00718203 | ||
| 222 | tlb[0x01]: 01004002 006d4201 01004005 006d4203 | ||
| 223 | tlb[0x02]: 01008002 006d0201 01008006 00004200 | ||
| 224 | tlb[0x03]: 0100c006 007f4202 0100c002 0064c202 | ||
| 225 | tlb[0x04]: 01110005 00774201 01110002 00774201 | ||
| 226 | tlb[0x05]: 01114005 00770201 01114002 00770201 | ||
| 227 | tlb[0x06]: 01118002 0076c201 01118005 0076c201 | ||
| 228 | ... | ||
| 229 | tlb[0x3d]: 010f4002 00790200 001f4002 0054ca02 | ||
| 230 | tlb[0x3e]: 010f8005 0078c201 010f8002 0078c201 | ||
| 231 | tlb[0x3f]: 001fc002 0056ca01 001fc005 00538a01 | ||
| 232 | |||
| 233 | (*) __debug_mmu.iamr[] | ||
| 234 | (*) __debug_mmu.damr[] | ||
| 235 | |||
| 236 | These receive the current IAMR and DAMR contents. These can be viewed with the _amr | ||
| 237 | GDB macro: | ||
| 238 | |||
| 239 | (gdb) _amr | ||
| 240 | AMRx DAMR IAMR | ||
| 241 | ==== ===================== ===================== | ||
| 242 | amr0 : L:c0000000 P:00000cb9 : L:c0000000 P:000004b9 | ||
| 243 | amr1 : L:01070005 P:006f9203 : L:0102c005 P:006a1201 | ||
| 244 | amr2 : L:d8d00000 P:00000000 : L:d8d00000 P:00000000 | ||
| 245 | amr3 : L:d8d04000 P:00534c0d : L:00000000 P:00000000 | ||
| 246 | amr4 : L:d8d08000 P:00554c0d : L:00000000 P:00000000 | ||
| 247 | amr5 : L:d8d0c000 P:00554c0d : L:00000000 P:00000000 | ||
| 248 | amr6 : L:d8d10000 P:00000000 : L:00000000 P:00000000 | ||
| 249 | amr7 : L:d8d14000 P:00000000 : L:00000000 P:00000000 | ||
| 250 | amr8 : L:d8d18000 P:00000000 | ||
| 251 | amr9 : L:d8d1c000 P:00000000 | ||
| 252 | amr10: L:d8d20000 P:00000000 | ||
| 253 | amr11: L:e0000000 P:e0000ccd | ||
| 254 | |||
| 255 | (*) The current task's page directory is bound to DAMR3. | ||
| 256 | |||
| 257 | This can be viewed with the _pgd GDB macro: | ||
| 258 | |||
| 259 | (gdb) _pgd | ||
| 260 | $3 = {{pge = {{ste = {0x554001, 0x554101, 0x554201, 0x554301, 0x554401, | ||
| 261 | 0x554501, 0x554601, 0x554701, 0x554801, 0x554901, 0x554a01, | ||
| 262 | 0x554b01, 0x554c01, 0x554d01, 0x554e01, 0x554f01, 0x555001, | ||
| 263 | 0x555101, 0x555201, 0x555301, 0x555401, 0x555501, 0x555601, | ||
| 264 | 0x555701, 0x555801, 0x555901, 0x555a01, 0x555b01, 0x555c01, | ||
| 265 | 0x555d01, 0x555e01, 0x555f01, 0x556001, 0x556101, 0x556201, | ||
| 266 | 0x556301, 0x556401, 0x556501, 0x556601, 0x556701, 0x556801, | ||
| 267 | 0x556901, 0x556a01, 0x556b01, 0x556c01, 0x556d01, 0x556e01, | ||
| 268 | 0x556f01, 0x557001, 0x557101, 0x557201, 0x557301, 0x557401, | ||
| 269 | 0x557501, 0x557601, 0x557701, 0x557801, 0x557901, 0x557a01, | ||
| 270 | 0x557b01, 0x557c01, 0x557d01, 0x557e01, 0x557f01}}}}, {pge = {{ | ||
| 271 | ste = {0x0 <repeats 64 times>}}}} <repeats 51 times>, {pge = {{ste = { | ||
| 272 | 0x248001, 0x248101, 0x248201, 0x248301, 0x248401, 0x248501, | ||
| 273 | 0x248601, 0x248701, 0x248801, 0x248901, 0x248a01, 0x248b01, | ||
| 274 | 0x248c01, 0x248d01, 0x248e01, 0x248f01, 0x249001, 0x249101, | ||
| 275 | 0x249201, 0x249301, 0x249401, 0x249501, 0x249601, 0x249701, | ||
| 276 | 0x249801, 0x249901, 0x249a01, 0x249b01, 0x249c01, 0x249d01, | ||
| 277 | 0x249e01, 0x249f01, 0x24a001, 0x24a101, 0x24a201, 0x24a301, | ||
| 278 | 0x24a401, 0x24a501, 0x24a601, 0x24a701, 0x24a801, 0x24a901, | ||
| 279 | 0x24aa01, 0x24ab01, 0x24ac01, 0x24ad01, 0x24ae01, 0x24af01, | ||
| 280 | 0x24b001, 0x24b101, 0x24b201, 0x24b301, 0x24b401, 0x24b501, | ||
| 281 | 0x24b601, 0x24b701, 0x24b801, 0x24b901, 0x24ba01, 0x24bb01, | ||
| 282 | 0x24bc01, 0x24bd01, 0x24be01, 0x24bf01}}}}, {pge = {{ste = { | ||
| 283 | 0x0 <repeats 64 times>}}}} <repeats 11 times>} | ||
| 284 | |||
| 285 | (*) The PTD last used by the instruction TLB miss handler is attached to DAMR4. | ||
| 286 | (*) The PTD last used by the data TLB miss handler is attached to DAMR5. | ||
| 287 | |||
| 288 | These can be viewed with the _ptd_i and _ptd_d GDB macros: | ||
| 289 | |||
| 290 | (gdb) _ptd_d | ||
| 291 | $5 = {{pte = 0x0} <repeats 127 times>, {pte = 0x539b01}, { | ||
| 292 | pte = 0x0} <repeats 896 times>, {pte = 0x719303}, {pte = 0x6d5303}, { | ||
| 293 | pte = 0x0}, {pte = 0x0}, {pte = 0x0}, {pte = 0x0}, {pte = 0x0}, { | ||
| 294 | pte = 0x0}, {pte = 0x0}, {pte = 0x0}, {pte = 0x0}, {pte = 0x6a1303}, { | ||
| 295 | pte = 0x0} <repeats 12 times>, {pte = 0x709303}, {pte = 0x0}, {pte = 0x0}, | ||
| 296 | {pte = 0x6fd303}, {pte = 0x6f9303}, {pte = 0x6f5303}, {pte = 0x0}, { | ||
| 297 | pte = 0x6ed303}, {pte = 0x531b01}, {pte = 0x50db01}, { | ||
| 298 | pte = 0x0} <repeats 13 times>, {pte = 0x5303}, {pte = 0x7f5303}, { | ||
| 299 | pte = 0x509b01}, {pte = 0x505b01}, {pte = 0x7c9303}, {pte = 0x7b9303}, { | ||
| 300 | pte = 0x7b5303}, {pte = 0x7b1303}, {pte = 0x7ad303}, {pte = 0x0}, { | ||
| 301 | pte = 0x0}, {pte = 0x7a1303}, {pte = 0x0}, {pte = 0x795303}, {pte = 0x0}, { | ||
| 302 | pte = 0x78d303}, {pte = 0x0}, {pte = 0x0}, {pte = 0x0}, {pte = 0x0}, { | ||
| 303 | pte = 0x0}, {pte = 0x775303}, {pte = 0x771303}, {pte = 0x76d303}, { | ||
| 304 | pte = 0x0}, {pte = 0x765303}, {pte = 0x7c5303}, {pte = 0x501b01}, { | ||
| 305 | pte = 0x4f1b01}, {pte = 0x4edb01}, {pte = 0x0}, {pte = 0x4f9b01}, { | ||
| 306 | pte = 0x4fdb01}, {pte = 0x0} <repeats 2992 times>} | ||
