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.
mac53c9x= [HW,SCSI]
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]
Format: <io>,<irq>,<dma>,<dma16>,<mpu_io>,<mpu_irq>,<joystick>
......
......@@ -61,11 +61,12 @@ config IA64_GENERIC
will run on any supported IA-64 system. However, if you configure
a kernel for your specific system, it will be faster and smaller.
generic For any supported IA-64 system
DIG-compliant For DIG ("Developer's Interface Guide") compliant systems
HP-zx1/sx1000 For HP systems
SGI-SN2 For SGI Altix systems
Ski-simulator For the HP simulator <http://www.hpl.hp.com/research/linux/ski/>
generic For any supported IA-64 system
DIG-compliant For DIG ("Developer's Interface Guide") compliant systems
HP-zx1/sx1000 For HP systems
HP-zx1/sx1000+swiotlb For HP systems with (broken) DMA-constrained devices.
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".
......@@ -78,6 +79,15 @@ config IA64_HP_ZX1
Build a kernel that runs on HP zx1 and sx1000 systems. This adds
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
bool "SGI-SN2"
help
......@@ -184,7 +194,7 @@ config VIRTUAL_MEM_MAP
config DISCONTIGMEM
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
help
Say Y to support efficient handling of discontiguous physical memory,
......@@ -321,7 +331,7 @@ menu "Power management and ACPI"
config PM
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
help
"Power Management" means that parts of your computer are shut
......
......@@ -16,7 +16,7 @@ config IA64_GRANULE_16MB
config IA64_GRANULE_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
......
......@@ -57,11 +57,13 @@ core-$(CONFIG_IA32_SUPPORT) += arch/ia64/ia32/
core-$(CONFIG_IA64_DIG) += arch/ia64/dig/
core-$(CONFIG_IA64_GENERIC) += 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/
drivers-$(CONFIG_PCI) += arch/ia64/pci/
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_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_OPROFILE) += arch/ia64/oprofile/
......
......@@ -6,3 +6,5 @@
#
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 @@
# 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
obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o
obj-$(CONFIG_IA64_GENERIC) += 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_IOSAPIC) += iosapic.o
obj-$(CONFIG_MODULES) += module.o
......
......@@ -113,6 +113,8 @@ acpi_get_sysname (void)
return "hpsim";
# elif defined (CONFIG_IA64_HP_ZX1)
return "hpzx1";
# elif defined (CONFIG_IA64_HP_ZX1_SWIOTLB)
return "hpzx1_swiotlb";
# elif defined (CONFIG_IA64_SGI_SN2)
return "sn2";
# elif defined (CONFIG_IA64_DIG)
......
/*
* 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>
* Stephane Eranian <eranian@hpl.hp.com>
* Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com>
......@@ -312,7 +312,28 @@ setup_arch (char **cmdline_p)
io_port_init();
#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
if (early_console_setup(*cmdline_p) == 0)
......
......@@ -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
* 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.
......@@ -113,10 +112,15 @@ __setup("swiotlb=", setup_io_tlb_npages);
* structures for the software IO TLB used to implement the PCI DMA API.
*/
void
swiotlb_init(void)
swiotlb_init_with_default_size (size_t default_size)
{
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
*/
......@@ -145,6 +149,12 @@ swiotlb_init(void)
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
address_needs_mapping(struct device *hwdev, dma_addr_t addr)
{
......
......@@ -144,7 +144,7 @@ config AGP_I460
config AGP_HP_ZX1
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
This option gives you AGP GART support for the HP ZX1 chipset
for IA64 processors.
......
......@@ -94,6 +94,8 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *);
# include <asm/machvec_dig.h>
# elif defined (CONFIG_IA64_HP_ZX1)
# include <asm/machvec_hpzx1.h>
# elif defined (CONFIG_IA64_HP_ZX1_SWIOTLB)
# include <asm/machvec_hpzx1_swiotlb.h>
# elif defined (CONFIG_IA64_SGI_SN2)
# include <asm/machvec_sn2.h>
# elif defined (CONFIG_IA64_GENERIC)
......
......@@ -4,7 +4,7 @@
#ifdef CONFIG_IA64_DIG
/* Max 8 Nodes */
#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 */
#define NODES_SHIFT 5
#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