diff options
-rw-r--r-- | Documentation/debugging-via-ohci1394.txt | 179 | ||||
-rw-r--r-- | arch/x86/kernel/setup_32.c | 11 | ||||
-rw-r--r-- | arch/x86/kernel/setup_64.c | 11 | ||||
-rw-r--r-- | drivers/Makefile | 2 | ||||
-rw-r--r-- | drivers/ieee1394/Makefile | 1 | ||||
-rw-r--r-- | drivers/ieee1394/init_ohci1394_dma.c | 285 | ||||
-rw-r--r-- | include/asm-x86/fixmap_32.h | 3 | ||||
-rw-r--r-- | include/asm-x86/fixmap_64.h | 3 | ||||
-rw-r--r-- | include/linux/init_ohci1394_dma.h | 4 | ||||
-rw-r--r-- | lib/Kconfig.debug | 28 |
10 files changed, 526 insertions, 1 deletions
diff --git a/Documentation/debugging-via-ohci1394.txt b/Documentation/debugging-via-ohci1394.txt new file mode 100644 index 000000000000..de4804e8b396 --- /dev/null +++ b/Documentation/debugging-via-ohci1394.txt | |||
@@ -0,0 +1,179 @@ | |||
1 | |||
2 | Using physical DMA provided by OHCI-1394 FireWire controllers for debugging | ||
3 | --------------------------------------------------------------------------- | ||
4 | |||
5 | Introduction | ||
6 | ------------ | ||
7 | |||
8 | Basically all FireWire controllers which are in use today are compliant | ||
9 | to the OHCI-1394 specification which defines the controller to be a PCI | ||
10 | bus master which uses DMA to offload data transfers from the CPU and has | ||
11 | a "Physical Response Unit" which executes specific requests by employing | ||
12 | PCI-Bus master DMA after applying filters defined by the OHCI-1394 driver. | ||
13 | |||
14 | Once properly configured, remote machines can send these requests to | ||
15 | ask the OHCI-1394 controller to perform read and write requests on | ||
16 | physical system memory and, for read requests, send the result of | ||
17 | the physical memory read back to the requester. | ||
18 | |||
19 | With that, it is possible to debug issues by reading interesting memory | ||
20 | locations such as buffers like the printk buffer or the process table. | ||
21 | |||
22 | Retrieving a full system memory dump is also possible over the FireWire, | ||
23 | using data transfer rates in the order of 10MB/s or more. | ||
24 | |||
25 | Memory access is currently limited to the low 4G of physical address | ||
26 | space which can be a problem on IA64 machines where memory is located | ||
27 | mostly above that limit, but it is rarely a problem on more common | ||
28 | hardware such as hardware based on x86, x86-64 and PowerPC. | ||
29 | |||
30 | Together with a early initialization of the OHCI-1394 controller for debugging, | ||
31 | this facility proved most useful for examining long debugs logs in the printk | ||
32 | buffer on to debug early boot problems in areas like ACPI where the system | ||
33 | fails to boot and other means for debugging (serial port) are either not | ||
34 | available (notebooks) or too slow for extensive debug information (like ACPI). | ||
35 | |||
36 | Drivers | ||
37 | ------- | ||
38 | |||
39 | The OHCI-1394 drivers in drivers/firewire and drivers/ieee1394 initialize | ||
40 | the OHCI-1394 controllers to a working state and can be used to enable | ||
41 | physical DMA. By default you only have to load the driver, and physical | ||
42 | DMA access will be granted to all remote nodes, but it can be turned off | ||
43 | when using the ohci1394 driver. | ||
44 | |||
45 | Because these drivers depend on the PCI enumeration to be completed, an | ||
46 | initialization routine which can runs pretty early (long before console_init(), | ||
47 | which makes the printk buffer appear on the console can be called) was written. | ||
48 | |||
49 | To activate it, enable CONFIG_PROVIDE_OHCI1394_DMA_INIT (Kernel hacking menu: | ||
50 | Provide code for enabling DMA over FireWire early on boot) and pass the | ||
51 | parameter "ohci1394_dma=early" to the recompiled kernel on boot. | ||
52 | |||
53 | Tools | ||
54 | ----- | ||
55 | |||
56 | firescope - Originally developed by Benjamin Herrenschmidt, Andi Kleen ported | ||
57 | it from PowerPC to x86 and x86_64 and added functionality, firescope can now | ||
58 | be used to view the printk buffer of a remote machine, even with live update. | ||
59 | |||
60 | Bernhard Kaindl enhanced firescope to support accessing 64-bit machines | ||
61 | from 32-bit firescope and vice versa: | ||
62 | - ftp://ftp.suse.de/private/bk/firewire/tools/firescope-0.2.2.tar.bz2 | ||
63 | |||
64 | and he implemented fast system dump (alpha version - read README.txt): | ||
65 | - ftp://ftp.suse.de/private/bk/firewire/tools/firedump-0.1.tar.bz2 | ||
66 | |||
67 | There is also a gdb proxy for firewire which allows to use gdb to access | ||
68 | data which can be referenced from symbols found by gdb in vmlinux: | ||
69 | - ftp://ftp.suse.de/private/bk/firewire/tools/fireproxy-0.33.tar.bz2 | ||
70 | |||
71 | The latest version of this gdb proxy (fireproxy-0.34) can communicate (not | ||
72 | yet stable) with kgdb over an memory-based communication module (kgdbom). | ||
73 | |||
74 | Getting Started | ||
75 | --------------- | ||
76 | |||
77 | The OHCI-1394 specification regulates that the OHCI-1394 controller must | ||
78 | disable all physical DMA on each bus reset. | ||
79 | |||
80 | This means that if you want to debug an issue in a system state where | ||
81 | interrupts are disabled and where no polling of the OHCI-1394 controller | ||
82 | for bus resets takes place, you have to establish any FireWire cable | ||
83 | connections and fully initialize all FireWire hardware __before__ the | ||
84 | system enters such state. | ||
85 | |||
86 | Step-by-step instructions for using firescope with early OHCI initialization: | ||
87 | |||
88 | 1) Verify that your hardware is supported: | ||
89 | |||
90 | Load the ohci1394 or the fw-ohci module and check your kernel logs. | ||
91 | You should see a line similar to | ||
92 | |||
93 | ohci1394: fw-host0: OHCI-1394 1.1 (PCI): IRQ=[18] MMIO=[fe9ff800-fe9fffff] | ||
94 | ... Max Packet=[2048] IR/IT contexts=[4/8] | ||
95 | |||
96 | when loading the driver. If you have no supported controller, many PCI, | ||
97 | CardBus and even some Express cards which are fully compliant to OHCI-1394 | ||
98 | specification are available. If it requires no driver for Windows operating | ||
99 | systems, it most likely is. Only specialized shops have cards which are not | ||
100 | compliant, they are based on TI PCILynx chips and require drivers for Win- | ||
101 | dows operating systems. | ||
102 | |||
103 | 2) Establish a working FireWire cable connection: | ||
104 | |||
105 | Any FireWire cable, as long at it provides electrically and mechanically | ||
106 | stable connection and has matching connectors (there are small 4-pin and | ||
107 | large 6-pin FireWire ports) will do. | ||
108 | |||
109 | If an driver is running on both machines you should see a line like | ||
110 | |||
111 | ieee1394: Node added: ID:BUS[0-01:1023] GUID[0090270001b84bba] | ||
112 | |||
113 | on both machines in the kernel log when the cable is plugged in | ||
114 | and connects the two machines. | ||
115 | |||
116 | 3) Test physical DMA using firescope: | ||
117 | |||
118 | On the debug host, | ||
119 | - load the raw1394 module, | ||
120 | - make sure that /dev/raw1394 is accessible, | ||
121 | then start firescope: | ||
122 | |||
123 | $ firescope | ||
124 | Port 0 (ohci1394) opened, 2 nodes detected | ||
125 | |||
126 | FireScope | ||
127 | --------- | ||
128 | Target : <unspecified> | ||
129 | Gen : 1 | ||
130 | [Ctrl-T] choose target | ||
131 | [Ctrl-H] this menu | ||
132 | [Ctrl-Q] quit | ||
133 | |||
134 | ------> Press Ctrl-T now, the output should be similar to: | ||
135 | |||
136 | 2 nodes available, local node is: 0 | ||
137 | 0: ffc0, uuid: 00000000 00000000 [LOCAL] | ||
138 | 1: ffc1, uuid: 00279000 ba4bb801 | ||
139 | |||
140 | Besides the [LOCAL] node, it must show another node without error message. | ||
141 | |||
142 | 4) Prepare for debugging with early OHCI-1394 initialization: | ||
143 | |||
144 | 4.1) Kernel compilation and installation on debug target | ||
145 | |||
146 | Compile the kernel to be debugged with CONFIG_PROVIDE_OHCI1394_DMA_INIT | ||
147 | (Kernel hacking: Provide code for enabling DMA over FireWire early on boot) | ||
148 | enabled and install it on the machine to be debugged (debug target). | ||
149 | |||
150 | 4.2) Transfer the System.map of the debugged kernel to the debug host | ||
151 | |||
152 | Copy the System.map of the kernel be debugged to the debug host (the host | ||
153 | which is connected to the debugged machine over the FireWire cable). | ||
154 | |||
155 | 5) Retrieving the printk buffer contents: | ||
156 | |||
157 | With the FireWire cable connected, the OHCI-1394 driver on the debugging | ||
158 | host loaded, reboot the debugged machine, booting the kernel which has | ||
159 | CONFIG_PROVIDE_OHCI1394_DMA_INIT enabled, with the option ohci1394_dma=early. | ||
160 | |||
161 | Then, on the debugging host, run firescope, for example by using -A: | ||
162 | |||
163 | firescope -A System.map-of-debug-target-kernel | ||
164 | |||
165 | Note: -A automatically attaches to the first non-local node. It only works | ||
166 | reliably if only connected two machines are connected using FireWire. | ||
167 | |||
168 | After having attached to the debug target, press Ctrl-D to view the | ||
169 | complete printk buffer or Ctrl-U to enter auto update mode and get an | ||
170 | updated live view of recent kernel messages logged on the debug target. | ||
171 | |||
172 | Call "firescope -h" to get more information on firescope's options. | ||
173 | |||
174 | Notes | ||
175 | ----- | ||
176 | Documentation and specifications: ftp://ftp.suse.de/private/bk/firewire/docs | ||
177 | |||
178 | FireWire is a trademark of Apple Inc. - for more information please refer to: | ||
179 | http://en.wikipedia.org/wiki/FireWire | ||
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 9c0ef4945a58..62adc5f20be5 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/dmi.h> | 45 | #include <linux/dmi.h> |
46 | #include <linux/pfn.h> | 46 | #include <linux/pfn.h> |
47 | #include <linux/pci.h> | 47 | #include <linux/pci.h> |
48 | #include <linux/init_ohci1394_dma.h> | ||
48 | 49 | ||
49 | #include <video/edid.h> | 50 | #include <video/edid.h> |
50 | 51 | ||
@@ -787,6 +788,16 @@ void __init setup_arch(char **cmdline_p) | |||
787 | smp_alloc_memory(); /* AP processor realmode stacks in low memory*/ | 788 | smp_alloc_memory(); /* AP processor realmode stacks in low memory*/ |
788 | #endif | 789 | #endif |
789 | paging_init(); | 790 | paging_init(); |
791 | |||
792 | /* | ||
793 | * NOTE: On x86-32, only from this point on, fixmaps are ready for use. | ||
794 | */ | ||
795 | |||
796 | #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT | ||
797 | if (init_ohci1394_dma_early) | ||
798 | init_ohci1394_dma_on_all_controllers(); | ||
799 | #endif | ||
800 | |||
790 | remapped_pgdat_init(); | 801 | remapped_pgdat_init(); |
791 | sparse_init(); | 802 | sparse_init(); |
792 | zone_sizes_init(); | 803 | zone_sizes_init(); |
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index 697533e86822..77fb87bf6e5a 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/dma-mapping.h> | 41 | #include <linux/dma-mapping.h> |
42 | #include <linux/ctype.h> | 42 | #include <linux/ctype.h> |
43 | #include <linux/uaccess.h> | 43 | #include <linux/uaccess.h> |
44 | #include <linux/init_ohci1394_dma.h> | ||
44 | 45 | ||
45 | #include <asm/mtrr.h> | 46 | #include <asm/mtrr.h> |
46 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
@@ -253,6 +254,11 @@ void __attribute__((weak)) __init memory_setup(void) | |||
253 | machine_specific_memory_setup(); | 254 | machine_specific_memory_setup(); |
254 | } | 255 | } |
255 | 256 | ||
257 | /* | ||
258 | * setup_arch - architecture-specific boot-time initializations | ||
259 | * | ||
260 | * Note: On x86_64, fixmaps are ready for use even before this is called. | ||
261 | */ | ||
256 | void __init setup_arch(char **cmdline_p) | 262 | void __init setup_arch(char **cmdline_p) |
257 | { | 263 | { |
258 | unsigned i; | 264 | unsigned i; |
@@ -302,6 +308,11 @@ void __init setup_arch(char **cmdline_p) | |||
302 | 308 | ||
303 | parse_early_param(); | 309 | parse_early_param(); |
304 | 310 | ||
311 | #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT | ||
312 | if (init_ohci1394_dma_early) | ||
313 | init_ohci1394_dma_on_all_controllers(); | ||
314 | #endif | ||
315 | |||
305 | finish_e820_parsing(); | 316 | finish_e820_parsing(); |
306 | 317 | ||
307 | early_gart_iommu_check(); | 318 | early_gart_iommu_check(); |
diff --git a/drivers/Makefile b/drivers/Makefile index 8cb37e3557d4..d92d4d82d001 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -38,7 +38,7 @@ obj-$(CONFIG_SCSI) += scsi/ | |||
38 | obj-$(CONFIG_ATA) += ata/ | 38 | obj-$(CONFIG_ATA) += ata/ |
39 | obj-$(CONFIG_FUSION) += message/ | 39 | obj-$(CONFIG_FUSION) += message/ |
40 | obj-$(CONFIG_FIREWIRE) += firewire/ | 40 | obj-$(CONFIG_FIREWIRE) += firewire/ |
41 | obj-$(CONFIG_IEEE1394) += ieee1394/ | 41 | obj-y += ieee1394/ |
42 | obj-$(CONFIG_UIO) += uio/ | 42 | obj-$(CONFIG_UIO) += uio/ |
43 | obj-y += cdrom/ | 43 | obj-y += cdrom/ |
44 | obj-y += auxdisplay/ | 44 | obj-y += auxdisplay/ |
diff --git a/drivers/ieee1394/Makefile b/drivers/ieee1394/Makefile index 489c133664d5..1f8153b57503 100644 --- a/drivers/ieee1394/Makefile +++ b/drivers/ieee1394/Makefile | |||
@@ -15,3 +15,4 @@ obj-$(CONFIG_IEEE1394_SBP2) += sbp2.o | |||
15 | obj-$(CONFIG_IEEE1394_DV1394) += dv1394.o | 15 | obj-$(CONFIG_IEEE1394_DV1394) += dv1394.o |
16 | obj-$(CONFIG_IEEE1394_ETH1394) += eth1394.o | 16 | obj-$(CONFIG_IEEE1394_ETH1394) += eth1394.o |
17 | 17 | ||
18 | obj-$(CONFIG_PROVIDE_OHCI1394_DMA_INIT) += init_ohci1394_dma.o | ||
diff --git a/drivers/ieee1394/init_ohci1394_dma.c b/drivers/ieee1394/init_ohci1394_dma.c new file mode 100644 index 000000000000..ddaab6eb8ace --- /dev/null +++ b/drivers/ieee1394/init_ohci1394_dma.c | |||
@@ -0,0 +1,285 @@ | |||
1 | /* | ||
2 | * init_ohci1394_dma.c - Initializes physical DMA on all OHCI 1394 controllers | ||
3 | * | ||
4 | * Copyright (C) 2006-2007 Bernhard Kaindl <bk@suse.de> | ||
5 | * | ||
6 | * Derived from drivers/ieee1394/ohci1394.c and arch/x86/kernel/early-quirks.c | ||
7 | * this file has functions to: | ||
8 | * - scan the PCI very early on boot for all OHCI 1394-compliant controllers | ||
9 | * - reset and initialize them and make them join the IEEE1394 bus and | ||
10 | * - enable physical DMA on them to allow remote debugging | ||
11 | * | ||
12 | * All code and data is marked as __init and __initdata, respective as | ||
13 | * during boot, all OHCI1394 controllers may be claimed by the firewire | ||
14 | * stack and at this point, this code should not touch them anymore. | ||
15 | * | ||
16 | * To use physical DMA after the initialization of the firewire stack, | ||
17 | * be sure that the stack enables it and (re-)attach after the bus reset | ||
18 | * which may be caused by the firewire stack initialization. | ||
19 | * | ||
20 | * This program is free software; you can redistribute it and/or modify | ||
21 | * it under the terms of the GNU General Public License as published by | ||
22 | * the Free Software Foundation; either version 2 of the License, or | ||
23 | * (at your option) any later version. | ||
24 | * | ||
25 | * This program is distributed in the hope that it will be useful, | ||
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
28 | * GNU General Public License for more details. | ||
29 | * | ||
30 | * You should have received a copy of the GNU General Public License | ||
31 | * along with this program; if not, write to the Free Software Foundation, | ||
32 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
33 | */ | ||
34 | |||
35 | #include <linux/interrupt.h> /* for ohci1394.h */ | ||
36 | #include <linux/delay.h> | ||
37 | #include <linux/pci.h> /* for PCI defines */ | ||
38 | #include <linux/init_ohci1394_dma.h> | ||
39 | #include <asm/pci-direct.h> /* for direct PCI config space access */ | ||
40 | #include <asm/fixmap.h> | ||
41 | |||
42 | #include "ieee1394_types.h" | ||
43 | #include "ohci1394.h" | ||
44 | |||
45 | int __initdata init_ohci1394_dma_early; | ||
46 | |||
47 | /* Reads a PHY register of an OHCI-1394 controller */ | ||
48 | static inline u8 __init get_phy_reg(struct ti_ohci *ohci, u8 addr) | ||
49 | { | ||
50 | int i; | ||
51 | quadlet_t r; | ||
52 | |||
53 | reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | 0x00008000); | ||
54 | |||
55 | for (i = 0; i < OHCI_LOOP_COUNT; i++) { | ||
56 | if (reg_read(ohci, OHCI1394_PhyControl) & 0x80000000) | ||
57 | break; | ||
58 | mdelay(1); | ||
59 | } | ||
60 | r = reg_read(ohci, OHCI1394_PhyControl); | ||
61 | |||
62 | return (r & 0x00ff0000) >> 16; | ||
63 | } | ||
64 | |||
65 | /* Writes to a PHY register of an OHCI-1394 controller */ | ||
66 | static inline void __init set_phy_reg(struct ti_ohci *ohci, u8 addr, u8 data) | ||
67 | { | ||
68 | int i; | ||
69 | |||
70 | reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | data | 0x00004000); | ||
71 | |||
72 | for (i = 0; i < OHCI_LOOP_COUNT; i++) { | ||
73 | u32 r = reg_read(ohci, OHCI1394_PhyControl); | ||
74 | if (!(r & 0x00004000)) | ||
75 | break; | ||
76 | mdelay(1); | ||
77 | } | ||
78 | } | ||
79 | |||
80 | /* Resets an OHCI-1394 controller (for sane state before initialization) */ | ||
81 | static inline void __init init_ohci1394_soft_reset(struct ti_ohci *ohci) { | ||
82 | int i; | ||
83 | |||
84 | reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset); | ||
85 | |||
86 | for (i = 0; i < OHCI_LOOP_COUNT; i++) { | ||
87 | if (!(reg_read(ohci, OHCI1394_HCControlSet) | ||
88 | & OHCI1394_HCControl_softReset)) | ||
89 | break; | ||
90 | mdelay(1); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | /* Basic OHCI-1394 register and port inititalization */ | ||
95 | static inline void __init init_ohci1394_initialize(struct ti_ohci *ohci) | ||
96 | { | ||
97 | quadlet_t bus_options; | ||
98 | int num_ports, i; | ||
99 | |||
100 | /* Put some defaults to these undefined bus options */ | ||
101 | bus_options = reg_read(ohci, OHCI1394_BusOptions); | ||
102 | bus_options |= 0x60000000; /* Enable CMC and ISC */ | ||
103 | bus_options &= ~0x00ff0000; /* XXX: Set cyc_clk_acc to zero for now */ | ||
104 | bus_options &= ~0x18000000; /* Disable PMC and BMC */ | ||
105 | reg_write(ohci, OHCI1394_BusOptions, bus_options); | ||
106 | |||
107 | /* Set the bus number */ | ||
108 | reg_write(ohci, OHCI1394_NodeID, 0x0000ffc0); | ||
109 | |||
110 | /* Enable posted writes */ | ||
111 | reg_write(ohci, OHCI1394_HCControlSet, | ||
112 | OHCI1394_HCControl_postedWriteEnable); | ||
113 | |||
114 | /* Clear link control register */ | ||
115 | reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff); | ||
116 | |||
117 | /* enable phys */ | ||
118 | reg_write(ohci, OHCI1394_LinkControlSet, | ||
119 | OHCI1394_LinkControl_RcvPhyPkt); | ||
120 | |||
121 | /* Don't accept phy packets into AR request context */ | ||
122 | reg_write(ohci, OHCI1394_LinkControlClear, 0x00000400); | ||
123 | |||
124 | /* Clear the Isochonouys interrupt masks */ | ||
125 | reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, 0xffffffff); | ||
126 | reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 0xffffffff); | ||
127 | reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, 0xffffffff); | ||
128 | reg_write(ohci, OHCI1394_IsoXmitIntEventClear, 0xffffffff); | ||
129 | |||
130 | /* Accept asyncronous transfer requests from all nodes for now */ | ||
131 | reg_write(ohci,OHCI1394_AsReqFilterHiSet, 0x80000000); | ||
132 | |||
133 | /* Specify asyncronous transfer retries */ | ||
134 | reg_write(ohci, OHCI1394_ATRetries, | ||
135 | OHCI1394_MAX_AT_REQ_RETRIES | | ||
136 | (OHCI1394_MAX_AT_RESP_RETRIES<<4) | | ||
137 | (OHCI1394_MAX_PHYS_RESP_RETRIES<<8)); | ||
138 | |||
139 | /* We don't want hardware swapping */ | ||
140 | reg_write(ohci, OHCI1394_HCControlClear, OHCI1394_HCControl_noByteSwap); | ||
141 | |||
142 | /* Enable link */ | ||
143 | reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_linkEnable); | ||
144 | |||
145 | /* If anything is connected to a port, make sure it is enabled */ | ||
146 | num_ports = get_phy_reg(ohci, 2) & 0xf; | ||
147 | for (i = 0; i < num_ports; i++) { | ||
148 | unsigned int status; | ||
149 | |||
150 | set_phy_reg(ohci, 7, i); | ||
151 | status = get_phy_reg(ohci, 8); | ||
152 | |||
153 | if (status & 0x20) | ||
154 | set_phy_reg(ohci, 8, status & ~1); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | /** | ||
159 | * init_ohci1394_wait_for_busresets - wait until bus resets are completed | ||
160 | * | ||
161 | * OHCI1394 initialization itself and any device going on- or offline | ||
162 | * and any cable issue cause a IEEE1394 bus reset. The OHCI1394 spec | ||
163 | * specifies that physical DMA is disabled on each bus reset and it | ||
164 | * has to be enabled after each bus reset when needed. We resort | ||
165 | * to polling here because on early boot, we have no interrupts. | ||
166 | */ | ||
167 | static inline void __init init_ohci1394_wait_for_busresets(struct ti_ohci *ohci) | ||
168 | { | ||
169 | int i, events; | ||
170 | |||
171 | for (i=0; i < 9; i++) { | ||
172 | mdelay(200); | ||
173 | events = reg_read(ohci, OHCI1394_IntEventSet); | ||
174 | if (events & OHCI1394_busReset) | ||
175 | reg_write(ohci, OHCI1394_IntEventClear, | ||
176 | OHCI1394_busReset); | ||
177 | } | ||
178 | } | ||
179 | |||
180 | /** | ||
181 | * init_ohci1394_enable_physical_dma - Enable physical DMA for remote debugging | ||
182 | * This enables remote DMA access over IEEE1394 from every host for the low | ||
183 | * 4GB of address space. DMA accesses above 4GB are not available currently. | ||
184 | */ | ||
185 | static inline void __init init_ohci1394_enable_physical_dma(struct ti_ohci *hci) | ||
186 | { | ||
187 | reg_write(hci, OHCI1394_PhyReqFilterHiSet, 0xffffffff); | ||
188 | reg_write(hci, OHCI1394_PhyReqFilterLoSet, 0xffffffff); | ||
189 | reg_write(hci, OHCI1394_PhyUpperBound, 0xffff0000); | ||
190 | } | ||
191 | |||
192 | /** | ||
193 | * init_ohci1394_reset_and_init_dma - init controller and enable DMA | ||
194 | * This initializes the given controller and enables physical DMA engine in it. | ||
195 | */ | ||
196 | static inline void __init init_ohci1394_reset_and_init_dma(struct ti_ohci *ohci) | ||
197 | { | ||
198 | /* Start off with a soft reset, clears everything to a sane state. */ | ||
199 | init_ohci1394_soft_reset(ohci); | ||
200 | |||
201 | /* Accessing some registers without LPS enabled may cause lock up */ | ||
202 | reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_LPS); | ||
203 | |||
204 | /* Disable and clear interrupts */ | ||
205 | reg_write(ohci, OHCI1394_IntEventClear, 0xffffffff); | ||
206 | reg_write(ohci, OHCI1394_IntMaskClear, 0xffffffff); | ||
207 | |||
208 | mdelay(50); /* Wait 50msec to make sure we have full link enabled */ | ||
209 | |||
210 | init_ohci1394_initialize(ohci); | ||
211 | /* | ||
212 | * The initialization causes at least one IEEE1394 bus reset. Enabling | ||
213 | * physical DMA only works *after* *all* bus resets have calmed down: | ||
214 | */ | ||
215 | init_ohci1394_wait_for_busresets(ohci); | ||
216 | |||
217 | /* We had to wait and do this now if we want to debug early problems */ | ||
218 | init_ohci1394_enable_physical_dma(ohci); | ||
219 | } | ||
220 | |||
221 | /** | ||
222 | * init_ohci1394_controller - Map the registers of the controller and init DMA | ||
223 | * This maps the registers of the specified controller and initializes it | ||
224 | */ | ||
225 | static inline void __init init_ohci1394_controller(int num, int slot, int func) | ||
226 | { | ||
227 | unsigned long ohci_base; | ||
228 | struct ti_ohci ohci; | ||
229 | |||
230 | printk(KERN_INFO "init_ohci1394_dma: initializing OHCI-1394" | ||
231 | " at %02x:%02x.%x\n", num, slot, func); | ||
232 | |||
233 | ohci_base = read_pci_config(num, slot, func, PCI_BASE_ADDRESS_0+(0<<2)) | ||
234 | & PCI_BASE_ADDRESS_MEM_MASK; | ||
235 | |||
236 | set_fixmap_nocache(FIX_OHCI1394_BASE, ohci_base); | ||
237 | |||
238 | ohci.registers = (void *)fix_to_virt(FIX_OHCI1394_BASE); | ||
239 | |||
240 | init_ohci1394_reset_and_init_dma(&ohci); | ||
241 | } | ||
242 | |||
243 | /** | ||
244 | * debug_init_ohci1394_dma - scan for OHCI1394 controllers and init DMA on them | ||
245 | * Scans the whole PCI space for OHCI1394 controllers and inits DMA on them | ||
246 | */ | ||
247 | void __init init_ohci1394_dma_on_all_controllers(void) | ||
248 | { | ||
249 | int num, slot, func; | ||
250 | |||
251 | if (!early_pci_allowed()) | ||
252 | return; | ||
253 | |||
254 | /* Poor man's PCI discovery, the only thing we can do at early boot */ | ||
255 | for (num = 0; num < 32; num++) { | ||
256 | for (slot = 0; slot < 32; slot++) { | ||
257 | for (func = 0; func < 8; func++) { | ||
258 | u32 class = read_pci_config(num,slot,func, | ||
259 | PCI_CLASS_REVISION); | ||
260 | if ((class == 0xffffffff)) | ||
261 | continue; /* No device at this func */ | ||
262 | |||
263 | if (class>>8 != PCI_CLASS_SERIAL_FIREWIRE_OHCI) | ||
264 | continue; /* Not an OHCI-1394 device */ | ||
265 | |||
266 | init_ohci1394_controller(num, slot, func); | ||
267 | break; /* Assume one controller per device */ | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | printk(KERN_INFO "init_ohci1394_dma: finished initializing OHCI DMA\n"); | ||
272 | } | ||
273 | |||
274 | /** | ||
275 | * setup_init_ohci1394_early - enables early OHCI1394 DMA initialization | ||
276 | */ | ||
277 | static int __init setup_ohci1394_dma(char *opt) | ||
278 | { | ||
279 | if (!strcmp(opt, "early")) | ||
280 | init_ohci1394_dma_early = 1; | ||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | /* passing ohci1394_dma=early on boot causes early OHCI1394 DMA initialization */ | ||
285 | early_param("ohci1394_dma", setup_ohci1394_dma); | ||
diff --git a/include/asm-x86/fixmap_32.h b/include/asm-x86/fixmap_32.h index fde140fd6d95..a7404d50686b 100644 --- a/include/asm-x86/fixmap_32.h +++ b/include/asm-x86/fixmap_32.h | |||
@@ -104,6 +104,9 @@ enum fixed_addresses { | |||
104 | (__end_of_permanent_fixed_addresses & 511), | 104 | (__end_of_permanent_fixed_addresses & 511), |
105 | FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_NESTING - 1, | 105 | FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_NESTING - 1, |
106 | FIX_WP_TEST, | 106 | FIX_WP_TEST, |
107 | #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT | ||
108 | FIX_OHCI1394_BASE, | ||
109 | #endif | ||
107 | __end_of_fixed_addresses | 110 | __end_of_fixed_addresses |
108 | }; | 111 | }; |
109 | 112 | ||
diff --git a/include/asm-x86/fixmap_64.h b/include/asm-x86/fixmap_64.h index 8f44782e5fe5..70ddb21e6458 100644 --- a/include/asm-x86/fixmap_64.h +++ b/include/asm-x86/fixmap_64.h | |||
@@ -44,6 +44,9 @@ enum fixed_addresses { | |||
44 | FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1, | 44 | FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1, |
45 | FIX_EFI_IO_MAP_LAST_PAGE, | 45 | FIX_EFI_IO_MAP_LAST_PAGE, |
46 | FIX_EFI_IO_MAP_FIRST_PAGE = FIX_EFI_IO_MAP_LAST_PAGE+MAX_EFI_IO_PAGES-1, | 46 | FIX_EFI_IO_MAP_FIRST_PAGE = FIX_EFI_IO_MAP_LAST_PAGE+MAX_EFI_IO_PAGES-1, |
47 | #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT | ||
48 | FIX_OHCI1394_BASE, | ||
49 | #endif | ||
47 | __end_of_fixed_addresses | 50 | __end_of_fixed_addresses |
48 | }; | 51 | }; |
49 | 52 | ||
diff --git a/include/linux/init_ohci1394_dma.h b/include/linux/init_ohci1394_dma.h new file mode 100644 index 000000000000..3c03a4bba5e4 --- /dev/null +++ b/include/linux/init_ohci1394_dma.h | |||
@@ -0,0 +1,4 @@ | |||
1 | #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT | ||
2 | extern int __initdata init_ohci1394_dma_early; | ||
3 | extern void __init init_ohci1394_dma_on_all_controllers(void); | ||
4 | #endif | ||
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index aa56e631580d..89f4035b526c 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -586,5 +586,33 @@ config LATENCYTOP | |||
586 | Enable this option if you want to use the LatencyTOP tool | 586 | Enable this option if you want to use the LatencyTOP tool |
587 | to find out which userspace is blocking on what kernel operations. | 587 | to find out which userspace is blocking on what kernel operations. |
588 | 588 | ||
589 | config PROVIDE_OHCI1394_DMA_INIT | ||
590 | bool "Provide code for enabling DMA over FireWire early on boot" | ||
591 | depends on PCI && X86 | ||
592 | help | ||
593 | If you want to debug problems which hang or crash the kernel early | ||
594 | on boot and the crashing machine has a FireWire port, you can use | ||
595 | this feature to remotely access the memory of the crashed machine | ||
596 | over FireWire. This employs remote DMA as part of the OHCI1394 | ||
597 | specification which is now the standard for FireWire controllers. | ||
598 | |||
599 | With remote DMA, you can monitor the printk buffer remotely using | ||
600 | firescope and access all memory below 4GB using fireproxy from gdb. | ||
601 | Even controlling a kernel debugger is possible using remote DMA. | ||
602 | |||
603 | Usage: | ||
604 | |||
605 | If ohci1394_dma=early is used as boot parameter, it will initialize | ||
606 | all OHCI1394 controllers which are found in the PCI config space. | ||
607 | |||
608 | As all changes to the FireWire bus such as enabling and disabling | ||
609 | devices cause a bus reset and thereby disable remote DMA for all | ||
610 | devices, be sure to have the cable plugged and FireWire enabled on | ||
611 | the debugging host before booting the debug target for debugging. | ||
612 | |||
613 | This code (~1k) is freed after boot. By then, the firewire stack | ||
614 | in charge of the OHCI-1394 controllers should be used instead. | ||
615 | |||
616 | See Documentation/debugging-via-ohci1394.txt for more information. | ||
589 | 617 | ||
590 | source "samples/Kconfig" | 618 | source "samples/Kconfig" |