aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2014-01-18 11:32:20 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2014-01-19 19:11:13 -0500
commitfcd46b34425da52703fe65b7f08850c509dcb0ed (patch)
treea133fd9d86111bbf3de37d882c00e8c3709eea8e
parent8bc588e0e585bc9085df75e84d4d5635f45cf360 (diff)
firewire: Enable remote DMA above 4 GB
This makes all of a machine's memory accessible to remote debugging via FireWire, using the physical response unit (i.e. RDMA) of OHCI-1394 link layer controllers. This requires actual support by the controller. The only ones currently known to support it are Agere/LSI FW643. Most if not all other OHCI-1394 controllers do not implement the optional Physical Upper Bound register. With them, RDMA will continue to be limited to the lowermost 4 GB. firewire-ohci's startup message in the kernel log is augmented to tell whether the controller does expose more than 4 GB to RDMA. While OHCI-1394 allows for a maximum Physical Upper Bound of 0xffff'0000'0000 (near 256 TB), this implementation sets it to 0x8000'0000'0000 (128 TB) in order to avoid interference with applications that require interrupt-served asynchronous request reception at respectively low addresses. Note, this change does not switch remote DMA on. It only increases the range of remote access to all memory (instead of just 4 GB) whenever remote DMA was switched on by other means. The latter is achieved by setting firewire-ohci's remote_dma parameter, or if the physical DMA filter is opened through firewire-sbp2. Derived from patch "firewire: Enable physical DMA above 4GB" by Peter Hurley <peter@hurleysoftware.com> from March 27, 2013. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
-rw-r--r--Documentation/debugging-via-ohci1394.txt13
-rw-r--r--drivers/firewire/core-transaction.c6
-rw-r--r--drivers/firewire/core.h3
-rw-r--r--drivers/firewire/ohci.c8
4 files changed, 20 insertions, 10 deletions
diff --git a/Documentation/debugging-via-ohci1394.txt b/Documentation/debugging-via-ohci1394.txt
index 73473aa8d861..fa0151a712f9 100644
--- a/Documentation/debugging-via-ohci1394.txt
+++ b/Documentation/debugging-via-ohci1394.txt
@@ -22,10 +22,12 @@ locations such as buffers like the printk buffer or the process table.
22Retrieving a full system memory dump is also possible over the FireWire, 22Retrieving a full system memory dump is also possible over the FireWire,
23using data transfer rates in the order of 10MB/s or more. 23using data transfer rates in the order of 10MB/s or more.
24 24
25Memory access is currently limited to the low 4G of physical address 25With most FireWire controllers, memory access is limited to the low 4 GB
26space which can be a problem on IA64 machines where memory is located 26of physical address space. This can be a problem on IA64 machines where
27mostly above that limit, but it is rarely a problem on more common 27memory is located mostly above that limit, but it is rarely a problem on
28hardware such as hardware based on x86, x86-64 and PowerPC. 28more common hardware such as x86, x86-64 and PowerPC. However, at least
29Agere/LSI FW643e and FW643e2 controllers are known to support access to
30physical addresses above 4 GB.
29 31
30Together with a early initialization of the OHCI-1394 controller for debugging, 32Together with a early initialization of the OHCI-1394 controller for debugging,
31this facility proved most useful for examining long debugs logs in the printk 33this facility proved most useful for examining long debugs logs in the printk
@@ -99,6 +101,9 @@ Step-by-step instructions for using firescope with early OHCI initialization:
99 compliant, they are based on TI PCILynx chips and require drivers for Win- 101 compliant, they are based on TI PCILynx chips and require drivers for Win-
100 dows operating systems. 102 dows operating systems.
101 103
104 The mentioned kernel log message contains ">4 GB phys DMA" in case of
105 OHCI-1394 controllers which support accesses above this limit.
106
1022) Establish a working FireWire cable connection: 1072) Establish a working FireWire cable connection:
103 108
104 Any FireWire cable, as long at it provides electrically and mechanically 109 Any FireWire cable, as long at it provides electrically and mechanically
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 0e799516a2ab..eb6935c8ad94 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -523,11 +523,11 @@ static DEFINE_SPINLOCK(address_handler_list_lock);
523static LIST_HEAD(address_handler_list); 523static LIST_HEAD(address_handler_list);
524 524
525const struct fw_address_region fw_high_memory_region = 525const struct fw_address_region fw_high_memory_region =
526 { .start = 0x000100000000ULL, .end = 0xffffe0000000ULL, }; 526 { .start = FW_MAX_PHYSICAL_RANGE, .end = 0xffffe0000000ULL, };
527EXPORT_SYMBOL(fw_high_memory_region); 527EXPORT_SYMBOL(fw_high_memory_region);
528 528
529static const struct fw_address_region low_memory_region = 529static const struct fw_address_region low_memory_region =
530 { .start = 0x000000000000ULL, .end = 0x000100000000ULL, }; 530 { .start = 0x000000000000ULL, .end = FW_MAX_PHYSICAL_RANGE, };
531 531
532#if 0 532#if 0
533const struct fw_address_region fw_private_region = 533const struct fw_address_region fw_private_region =
@@ -1217,7 +1217,7 @@ static void handle_low_memory(struct fw_card *card, struct fw_request *request,
1217} 1217}
1218 1218
1219static struct fw_address_handler low_memory = { 1219static struct fw_address_handler low_memory = {
1220 .length = 0x000100000000ULL, 1220 .length = FW_MAX_PHYSICAL_RANGE,
1221 .address_callback = handle_low_memory, 1221 .address_callback = handle_low_memory,
1222}; 1222};
1223 1223
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h
index 515a42c786d0..c98764aeeec6 100644
--- a/drivers/firewire/core.h
+++ b/drivers/firewire/core.h
@@ -237,6 +237,9 @@ static inline bool is_next_generation(int new_generation, int old_generation)
237 237
238#define LOCAL_BUS 0xffc0 238#define LOCAL_BUS 0xffc0
239 239
240/* arbitrarily chosen maximum range for physical DMA: 128 TB */
241#define FW_MAX_PHYSICAL_RANGE (128ULL << 40)
242
240void fw_core_handle_request(struct fw_card *card, struct fw_packet *request); 243void fw_core_handle_request(struct fw_card *card, struct fw_packet *request);
241void fw_core_handle_response(struct fw_card *card, struct fw_packet *packet); 244void fw_core_handle_response(struct fw_card *card, struct fw_packet *packet);
242int fw_get_response_length(struct fw_request *request); 245int fw_get_response_length(struct fw_request *request);
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 036fb3bd5659..6f74d8d3f700 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -2367,7 +2367,7 @@ static int ohci_enable(struct fw_card *card,
2367 reg_write(ohci, OHCI1394_FairnessControl, 0); 2367 reg_write(ohci, OHCI1394_FairnessControl, 0);
2368 card->priority_budget_implemented = ohci->pri_req_max != 0; 2368 card->priority_budget_implemented = ohci->pri_req_max != 0;
2369 2369
2370 reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000); 2370 reg_write(ohci, OHCI1394_PhyUpperBound, FW_MAX_PHYSICAL_RANGE >> 16);
2371 reg_write(ohci, OHCI1394_IntEventClear, ~0); 2371 reg_write(ohci, OHCI1394_IntEventClear, ~0);
2372 reg_write(ohci, OHCI1394_IntMaskClear, ~0); 2372 reg_write(ohci, OHCI1394_IntMaskClear, ~0);
2373 2373
@@ -3723,9 +3723,11 @@ static int pci_probe(struct pci_dev *dev,
3723 version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; 3723 version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
3724 ohci_notice(ohci, 3724 ohci_notice(ohci,
3725 "added OHCI v%x.%x device as card %d, " 3725 "added OHCI v%x.%x device as card %d, "
3726 "%d IR + %d IT contexts, quirks 0x%x\n", 3726 "%d IR + %d IT contexts, quirks 0x%x%s\n",
3727 version >> 16, version & 0xff, ohci->card.index, 3727 version >> 16, version & 0xff, ohci->card.index,
3728 ohci->n_ir, ohci->n_it, ohci->quirks); 3728 ohci->n_ir, ohci->n_it, ohci->quirks,
3729 reg_read(ohci, OHCI1394_PhyUpperBound) ?
3730 ", >4 GB phys DMA" : "");
3729 3731
3730 return 0; 3732 return 0;
3731 3733