Commit b733ce21 authored by David Mosberger's avatar David Mosberger

[IA64] add hpzx1_swiotlb machine-vector

I was in need of a 3.3V/dual-voltage-capable PCI sound-card and, as
luck would have it, the only card of that sort in the local computer
store was one that _still_ has a DMA engine that cannot even DMA to
all 32 bits (it's limited to 28 bits).  Hard to believe, but true (the
card in question is a "SoundBlaster Live! 24-bit" with a CA0106 chip;
stay away from that one if you can...).

Anyhow, since I don't like it when PCI cards don't work in my machine,
I created the attached patch which adds a new machine-vector to enable
support of such broken cards.

With the patch applied, you can either configure the kernel for
"HP-zx1/sx1000+swiotlb" or configure for "generic" and boot with
option "machvec=hpzx1_swiotlb" to enable support for broken PCI
devices.

The patch works as follows: the new machvec implements a I/O MMU which
will use the hardware I/O MMU whenever possible but fall back on the
software I/O TLB when encountering a device that can't be supported by
the hardware I/O MMU.  Fortunately, we don't have to mess with
MAX_DMA_ADDRESS or create a new zone: the software I/O TLB allocates
its memory as low as possible and early in the boot-process, so on any
machine with low memory, we're pretty much guaranteed that we'll get a
reasonable amount of low memory, which is all we need to properly support
broken PCI cards.

Note that I made a small change to swiotlb.c: I added a
swiotlb_init_with_default_size() function to let the new I/O MMU
initialize the software I/O TLB with less than 64MB (which is way too
much for the limited uses we'll see for the broken PCI devices; for
example, the CA0106 chip allocates only coherent buffers of about
128KB).

The patch has been tested on a zx1 machine in the generic, hpzx1, and
hpzx1_swiotlb configuration.

Thanks to Alex Williamson for the suggestion of doing this via a
completely separate machvec.
Signed-off-by: default avatarDavid Mosberger-Tang <davidm@hpl.hp.com>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent 04c73690
...@@ -673,7 +673,11 @@ running once the system is up. ...@@ -673,7 +673,11 @@ running once the system is up.
mac53c9x= [HW,SCSI] mac53c9x= [HW,SCSI]
Format: <num_esps>,<disconnect>,<nosync>,<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags> Format: <num_esps>,<disconnect>,<nosync>,<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
machvec= [IA64]
Force the use of a particular machine-vector (machvec) in a generic
kernel. Example: machvec=hpzx1_swiotlb
mad16= [HW,OSS] mad16= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma16>,<mpu_io>,<mpu_irq>,<joystick> Format: <io>,<irq>,<dma>,<dma16>,<mpu_io>,<mpu_irq>,<joystick>
......
...@@ -61,11 +61,12 @@ config IA64_GENERIC ...@@ -61,11 +61,12 @@ config IA64_GENERIC
will run on any supported IA-64 system. However, if you configure will run on any supported IA-64 system. However, if you configure
a kernel for your specific system, it will be faster and smaller. a kernel for your specific system, it will be faster and smaller.
generic For any supported IA-64 system generic For any supported IA-64 system
DIG-compliant For DIG ("Developer's Interface Guide") compliant systems DIG-compliant For DIG ("Developer's Interface Guide") compliant systems
HP-zx1/sx1000 For HP systems HP-zx1/sx1000 For HP systems
SGI-SN2 For SGI Altix systems HP-zx1/sx1000+swiotlb For HP systems with (broken) DMA-constrained devices.
Ski-simulator For the HP simulator <http://www.hpl.hp.com/research/linux/ski/> SGI-SN2 For SGI Altix systems
Ski-simulator For the HP simulator <http://www.hpl.hp.com/research/linux/ski/>
If you don't know what to do, choose "generic". If you don't know what to do, choose "generic".
...@@ -78,6 +79,15 @@ config IA64_HP_ZX1 ...@@ -78,6 +79,15 @@ config IA64_HP_ZX1
Build a kernel that runs on HP zx1 and sx1000 systems. This adds Build a kernel that runs on HP zx1 and sx1000 systems. This adds
support for the HP I/O MMU. support for the HP I/O MMU.
config IA64_HP_ZX1_SWIOTLB
bool "HP-zx1/sx1000 with software I/O TLB"
help
Build a kernel that runs on HP zx1 and sx1000 systems even when they
have broken PCI devices which cannot DMA to full 32 bits. Apart
from support for the HP I/O MMU, this includes support for the software
I/O TLB, which allows supporting the broken devices at the expense of
wasting some kernel memory (about 2MB by default).
config IA64_SGI_SN2 config IA64_SGI_SN2
bool "SGI-SN2" bool "SGI-SN2"
help help
...@@ -184,7 +194,7 @@ config VIRTUAL_MEM_MAP ...@@ -184,7 +194,7 @@ config VIRTUAL_MEM_MAP
config DISCONTIGMEM config DISCONTIGMEM
bool "Discontiguous memory support" bool "Discontiguous memory support"
depends on (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1) && NUMA && VIRTUAL_MEM_MAP depends on (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) && NUMA && VIRTUAL_MEM_MAP
default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA
help help
Say Y to support efficient handling of discontiguous physical memory, Say Y to support efficient handling of discontiguous physical memory,
...@@ -321,7 +331,7 @@ menu "Power management and ACPI" ...@@ -321,7 +331,7 @@ menu "Power management and ACPI"
config PM config PM
bool "Power Management support" bool "Power Management support"
depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB
default y default y
help help
"Power Management" means that parts of your computer are shut "Power Management" means that parts of your computer are shut
......
...@@ -16,7 +16,7 @@ config IA64_GRANULE_16MB ...@@ -16,7 +16,7 @@ config IA64_GRANULE_16MB
config IA64_GRANULE_64MB config IA64_GRANULE_64MB
bool "64MB" bool "64MB"
depends on !(IA64_GENERIC || IA64_HP_ZX1 || IA64_SGI_SN2) depends on !(IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_SGI_SN2)
endchoice endchoice
......
...@@ -57,11 +57,13 @@ core-$(CONFIG_IA32_SUPPORT) += arch/ia64/ia32/ ...@@ -57,11 +57,13 @@ core-$(CONFIG_IA32_SUPPORT) += arch/ia64/ia32/
core-$(CONFIG_IA64_DIG) += arch/ia64/dig/ core-$(CONFIG_IA64_DIG) += arch/ia64/dig/
core-$(CONFIG_IA64_GENERIC) += arch/ia64/dig/ core-$(CONFIG_IA64_GENERIC) += arch/ia64/dig/
core-$(CONFIG_IA64_HP_ZX1) += arch/ia64/dig/ core-$(CONFIG_IA64_HP_ZX1) += arch/ia64/dig/
core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/
core-$(CONFIG_IA64_SGI_SN2) += arch/ia64/sn/ core-$(CONFIG_IA64_SGI_SN2) += arch/ia64/sn/
drivers-$(CONFIG_PCI) += arch/ia64/pci/ drivers-$(CONFIG_PCI) += arch/ia64/pci/
drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/ drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/
drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
drivers-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/ drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/
drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/ drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/
......
...@@ -6,3 +6,5 @@ ...@@ -6,3 +6,5 @@
# #
obj-y := sba_iommu.o obj-y := sba_iommu.o
obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += hwsw_iommu.o
obj-$(CONFIG_IA64_GENERIC) += hwsw_iommu.o
...@@ -5,4 +5,4 @@ ...@@ -5,4 +5,4 @@
# Copyright (C) Alex Williamson (alex_williamson@hp.com) # Copyright (C) Alex Williamson (alex_williamson@hp.com)
# #
obj-$(CONFIG_IA64_GENERIC) += hpzx1_machvec.o obj-$(CONFIG_IA64_GENERIC) += hpzx1_machvec.o hpzx1_swiotlb_machvec.o
...@@ -12,6 +12,7 @@ obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o i ...@@ -12,6 +12,7 @@ obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o i
obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o
obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o
obj-$(CONFIG_IA64_HP_ZX1) += acpi-ext.o obj-$(CONFIG_IA64_HP_ZX1) += acpi-ext.o
obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += acpi-ext.o
obj-$(CONFIG_IA64_PALINFO) += palinfo.o obj-$(CONFIG_IA64_PALINFO) += palinfo.o
obj-$(CONFIG_IOSAPIC) += iosapic.o obj-$(CONFIG_IOSAPIC) += iosapic.o
obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_MODULES) += module.o
......
...@@ -113,6 +113,8 @@ acpi_get_sysname (void) ...@@ -113,6 +113,8 @@ acpi_get_sysname (void)
return "hpsim"; return "hpsim";
# elif defined (CONFIG_IA64_HP_ZX1) # elif defined (CONFIG_IA64_HP_ZX1)
return "hpzx1"; return "hpzx1";
# elif defined (CONFIG_IA64_HP_ZX1_SWIOTLB)
return "hpzx1_swiotlb";
# elif defined (CONFIG_IA64_SGI_SN2) # elif defined (CONFIG_IA64_SGI_SN2)
return "sn2"; return "sn2";
# elif defined (CONFIG_IA64_DIG) # elif defined (CONFIG_IA64_DIG)
......
/* /*
* Architecture-specific setup. * Architecture-specific setup.
* *
* Copyright (C) 1998-2001, 2003 Hewlett-Packard Co * Copyright (C) 1998-2001, 2003-2004 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com> * David Mosberger-Tang <davidm@hpl.hp.com>
* Stephane Eranian <eranian@hpl.hp.com> * Stephane Eranian <eranian@hpl.hp.com>
* Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com> * Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com>
...@@ -312,7 +312,28 @@ setup_arch (char **cmdline_p) ...@@ -312,7 +312,28 @@ setup_arch (char **cmdline_p)
io_port_init(); io_port_init();
#ifdef CONFIG_IA64_GENERIC #ifdef CONFIG_IA64_GENERIC
machvec_init(acpi_get_sysname()); {
const char *mvec_name = strstr (*cmdline_p, "machvec=");
char str[64];
if (mvec_name) {
const char *end;
size_t len;
mvec_name += 8;
end = strchr (mvec_name, ' ');
if (end)
len = end - mvec_name;
else
len = strlen (mvec_name);
len = min(len, sizeof (str) - 1);
strncpy (str, mvec_name, len);
str[len] = '\0';
mvec_name = str;
} else
mvec_name = acpi_get_sysname();
machvec_init(mvec_name);
}
#endif #endif
if (early_console_setup(*cmdline_p) == 0) if (early_console_setup(*cmdline_p) == 0)
......
...@@ -61,9 +61,8 @@ static char *io_tlb_start, *io_tlb_end; ...@@ -61,9 +61,8 @@ static char *io_tlb_start, *io_tlb_end;
/* /*
* The number of IO TLB blocks (in groups of 64) betweeen io_tlb_start and * The number of IO TLB blocks (in groups of 64) betweeen io_tlb_start and
* io_tlb_end. This is command line adjustable via setup_io_tlb_npages. * io_tlb_end. This is command line adjustable via setup_io_tlb_npages.
* Default to 64MB.
*/ */
static unsigned long io_tlb_nslabs = 32768; static unsigned long io_tlb_nslabs;
/* /*
* When the IOMMU overflows we return a fallback buffer. This sets the size. * When the IOMMU overflows we return a fallback buffer. This sets the size.
...@@ -113,10 +112,15 @@ __setup("swiotlb=", setup_io_tlb_npages); ...@@ -113,10 +112,15 @@ __setup("swiotlb=", setup_io_tlb_npages);
* structures for the software IO TLB used to implement the PCI DMA API. * structures for the software IO TLB used to implement the PCI DMA API.
*/ */
void void
swiotlb_init(void) swiotlb_init_with_default_size (size_t default_size)
{ {
unsigned long i; unsigned long i;
if (!io_tlb_nslabs) {
io_tlb_nslabs = (default_size >> PAGE_SHIFT);
io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
}
/* /*
* Get IO TLB memory from the low pages * Get IO TLB memory from the low pages
*/ */
...@@ -145,6 +149,12 @@ swiotlb_init(void) ...@@ -145,6 +149,12 @@ swiotlb_init(void)
virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end)); virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end));
} }
void
swiotlb_init (void)
{
swiotlb_init_with_default_size(64 * (1<<20)); /* default to 64MB */
}
static inline int static inline int
address_needs_mapping(struct device *hwdev, dma_addr_t addr) address_needs_mapping(struct device *hwdev, dma_addr_t addr)
{ {
......
...@@ -144,7 +144,7 @@ config AGP_I460 ...@@ -144,7 +144,7 @@ config AGP_I460
config AGP_HP_ZX1 config AGP_HP_ZX1
tristate "HP ZX1 chipset AGP support" tristate "HP ZX1 chipset AGP support"
depends on AGP && (IA64_HP_ZX1 || IA64_GENERIC) depends on AGP && (IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_GENERIC)
help help
This option gives you AGP GART support for the HP ZX1 chipset This option gives you AGP GART support for the HP ZX1 chipset
for IA64 processors. for IA64 processors.
......
...@@ -94,6 +94,8 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *); ...@@ -94,6 +94,8 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *);
# include <asm/machvec_dig.h> # include <asm/machvec_dig.h>
# elif defined (CONFIG_IA64_HP_ZX1) # elif defined (CONFIG_IA64_HP_ZX1)
# include <asm/machvec_hpzx1.h> # include <asm/machvec_hpzx1.h>
# elif defined (CONFIG_IA64_HP_ZX1_SWIOTLB)
# include <asm/machvec_hpzx1_swiotlb.h>
# elif defined (CONFIG_IA64_SGI_SN2) # elif defined (CONFIG_IA64_SGI_SN2)
# include <asm/machvec_sn2.h> # include <asm/machvec_sn2.h>
# elif defined (CONFIG_IA64_GENERIC) # elif defined (CONFIG_IA64_GENERIC)
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#ifdef CONFIG_IA64_DIG #ifdef CONFIG_IA64_DIG
/* Max 8 Nodes */ /* Max 8 Nodes */
#define NODES_SHIFT 3 #define NODES_SHIFT 3
#elif defined(CONFIG_IA64_HP_ZX1) #elif defined(CONFIG_IA64_HP_ZX1) || defined(CONFIG_IA64_HP_ZX1_SWIOTLB)
/* Max 32 Nodes */ /* Max 32 Nodes */
#define NODES_SHIFT 5 #define NODES_SHIFT 5
#elif defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC) #elif defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment