Cobalt fixes
Some may have been following the beginning of this thread on linux-kernel, see for example
http://www.opensubscriber.com/message/[email protected]/8161812.html
for non-subscribers. Linus has reverted the offending patch fd6e732186ab522c812ab19c2c5e5befb8ec8115 in question so now the PCI and I/O port code needs to be fixed up to be able to handle such a setup.
A test report of this patch which is meant to be applied on top of today's lmo git kernel on a Cobalt would be appreciated.
Ralf
[MIPS] Cobalt: Sort out legacy I/O port addressing.
Thanks to the brainfucked GT-64111 which passes CPU addresses in the PCI I/O window to the PCI bus without any translation a Cobalt cannot generate a low I/O port address that is below < 0x10000000 in the GT-64111 default configuration. Fortunately the VIA VT82C586 southbridge used in Cobalts only decodes the low 16 bits of the I/O port address for its legacy devices. This can be exploited to generate equivalent addresses but need to use an address different from mips_io_port_base as the base to work. In addition PCI fixups need to be prevented from tinkering with legacy addresses.
arch/mips/cobalt/pci.c +3 -3
@@ -24,8 +24,8 @@ static struct resource cobalt_mem_resource = { };static struct resource cobalt_io_resource = { - .start =0x1000 , - .end =GT_DEF_PCI0_IO_SIZE -1 , + .start =GT_DEF_PCI0_IO_BASE +0x1000 , + .end =GT_DEF_PCI0_IO_BASE +GT_DEF_PCI0_IO_SIZE -1 , .name ="PCI I/O" , .flags =IORESOURCE_IO , };
@@ -34,7 +34,7 @@ static struct pci_controller cobalt_pci_controller = { .pci_ops = >64xxx_pci0_ops, .mem_resource = &cobalt_mem_resource, .io_resource = &cobalt_io_resource, - .io_offset = 0 - GT_DEF_PCI0_IO_BASE, + .io_offset = 0, .io_map_base = CKSEG1ADDR(GT_DEF_PCI0_IO_BASE), };
arch/mips/cobalt/setup.c +3 -2
@@ -79,10 +79,11 @@ void __init plat_mem_setup(void) _machine_halt = cobalt_machine_halt; pm_power_off = cobalt_machine_halt; -set_io_port_base (CKSEG1ADDR (GT_DEF_PCI0_IO_BASE )); +set_io_port_base (IO_BASE ); +set_legacy_io_port_base (CKSEG1ADDR (GT_DEF_PCI0_IO_BASE ));/* I/O port resource must include LCD/buttons */ - ioport_resource.end =0x0fffffff ; + ioport_resource.end =GT_DEF_PCI0_IO_BASE +GT_DEF_PCI0_IO_SIZE -1 ;/* These resources have been reserved by VIA SuperI/O chip. */ for (i =0 ; i <ARRAY_SIZE (cobalt_reserved_resources); i++)
arch/mips/kernel/setup.c +5 -2
@@ -60,11 +60,14 @@ static char command_line[CL_SIZE];char arcs_cmdline[CL_SIZE ]=CONFIG_CMDLINE ;/* -* mips_io_port_base is the begin of the address space to which x86 style -* I/O ports are mapped. +* mips_io_port_base is the base of the address range into which the I/O ports +* are mapped. mips_legacy_io_port_base is the same but used only for legacy +* addresses below legacy_io_port_top. */ const unsigned long mips_io_port_base__read_mostly =-1 ;EXPORT_SYMBOL (mips_io_port_base); +const unsigned long mips_legacy_io_port_base__read_mostly =-1 ; +EXPORT_SYMBOL (mips_legacy_io_port_base);/* * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped
arch/mips/pci/fixup-cobalt.c +12 -0
@@ -51,6 +51,18 @@ static void qube_raq_galileo_early_fixup(struct pci_dev *dev)DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_MARVELL ,PCI_DEVICE_ID_MARVELL_GT64111 , qube_raq_galileo_early_fixup); +static void __devinit cobalt_via_ide_native_mode_fixup (struct pci_dev *dev) +{ +unsigned char pif; + +pci_read_config_byte (dev,PCI_CLASS_PROG , &pif); + pif |=4 ; +pci_write_config_byte (dev,PCI_CLASS_PROG , pif); +} + +DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_VIA ,PCI_DEVICE_ID_VIA_82C586_1 , + cobalt_via_ide_native_mode_fixup); +static void qube_raq_via_bmIDE_fixup (struct pci_dev *dev) {unsigned short cfgword;
arch/mips/pci/pci.c +2 -0
@@ -242,6 +242,8 @@ static void pcibios_fixup_device_resources(struct pci_dev *dev,for (i =0 ; i <PCI_NUM_RESOURCES ; i++) {if (!dev->resource[i].start)continue ; +if (dev->resource[i].flags &IORESOURCE_PCI_FIXED ) +continue ;if (dev->resource[i].flags &IORESOURCE_IO ) offset = hose->io_offset;else if (dev->resource[i].flags &IORESOURCE_MEM )
include/asm-mips/io.h +27 -6
@@ -53,11 +53,16 @@/* * On MIPS I/O ports are memory mapped, so we access them using normal * load/store instructions. mips_io_port_base is the virtual address to -* which all ports are being mapped. For sake of efficiency some code -* assumes that this is an address that can be loaded with a single lui -* instruction, so the lower 16 bits must be zero. Should be true on -* on any sane architecture; generic code does not use this assumption. +* which all ports are being mapped. mips_legacy_io_port_base the same +* but used for ports below legacy_io_port_top. This special treatment +* of legacy addresses is used for example on Cobalt systems where the +* GT-64111 system controller doesn't allow access to low ports but aliasing +* can be exploited to access them anyway. So on a GT-64111 system +* mips_legacy_io_port_base would point to the base of the address range +* to which I/O ports are aliased. Having the legacy_io_port_top default of +* zero leaves this special treatment disabled by default. */ +extern const unsigned long mips_legacy_io_port_base;extern const unsigned long mips_io_port_base;/*
@@ -75,6 +80,12 @@ static inline void set_io_port_base(unsigned long base)barrier (); } +static inline void set_legacy_io_port_base (unsigned long base) +{ + * (unsigned long *) &mips_legacy_io_port_base = base; +barrier (); +} +/* * Thanks to James van Artsdalen for a better timing-fix than * the two short jumps: using outb's to a nonexistent port seems
@@ -375,9 +386,14 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \ static inline void pfx##out##bwlq##p(type val, unsigned long port) \ { \ volatile type *__addr; \ + unsigned long __vaddr; \ type __val; \ \ - __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \ + if (port < legacy_io_port_top) \ + __vaddr = mips_legacy_io_port_base + port; \ + else \ + __vaddr = mips_io_port_base + port; \ + __addr = (void *)__swizzle_addr_##bwlq(__vaddr); \ \ __val = pfx##ioswab##bwlq(__addr, val); \ \
@@ -391,9 +407,14 @@ static inline void pfx##out##bwlq##p(type val, unsigned long port) \ static inline type pfx##in##bwlq##p(unsigned long port) \ { \ volatile type *__addr; \ + unsigned long __vaddr; \ type __val; \ \ - __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \ + if (port < legacy_io_port_top) \ + __vaddr = mips_legacy_io_port_base + port; \ + else \ + __vaddr = mips_io_port_base + port; \ + __addr = (void *)__swizzle_addr_##bwlq(__vaddr); \ \ BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \ \
include/asm-mips/mach-cobalt/mangle-port.h new file +27 -0
@@ -0,0 +1,27 @@ +/* +* This file is subject to the terms and conditions of the GNU General Public +* License. See the file "COPYING" in the main directory of this archive +* for more details. +* +* Copyright (C) 2003, 2004, 2007 Ralf Baechle ([email protected]) +*/ +#ifndef __ASM_MACH_COBALT_MANGLE_PORT_H +#define __ASM_MACH_COBALT_MANGLE_PORT_H + +#define __swizzle_addr_b (port) (port) +#define __swizzle_addr_w (port) (port) +#define __swizzle_addr_l (port) (port) +#define __swizzle_addr_q (port) (port) + +# define ioswabb (a, x) (x) +# define __mem_ioswabb (a, x) (x) +# define ioswabw (a, x) (x) +# define __mem_ioswabw (a, x) cpu_to_le16(x) +# define ioswabl (a, x) (x) +# define __mem_ioswabl (a, x) cpu_to_le32(x) +# define ioswabq (a, x) (x) +# define __mem_ioswabq (a, x) cpu_to_le32(x) + +#define legacy_io_port_top 0 + +#endif /* __ASM_MACH_COBALT_MANGLE_PORT_H */
include/asm-mips/mach-generic/mangle-port.h +2 -0
@@ -49,4 +49,6 @@#endif +#define legacy_io_port_top 0 +#endif /* __ASM_MACH_GENERIC_MANGLE_PORT_H */
Quoted 11 lines · On Tue, 11 Dec 2007 12:12:20 +0000 Ralf Baechle <[email protected]> wrote:
Some may have been following the beginning of this thread on linux-kernel, see for example
http://www.opensubscriber.com/message/[email protected]/8161812.html
for non-subscribers. Linus has reverted the offending patch
fd6e732186ab522c812ab19c2c5e5befb8ec8115in question so now the PCI and I/O port code needs to be fixed up to be able to handle such a setup.A test report of this patch which is meant to be applied on top of today's lmo git kernel on a Cobalt would be appreciated.
It breaks all I/O port device(LCD, tulip, VIA ata) drivers.
Yoichi
Quoted 5 lines · Yoichi Yuasa
Quoted 5 lines
Some may have been following the beginning of this thread on linux-kernel, see for example
http://www.opensubscriber.com/message/[email protected]/8161812.html
Quoted 8 lines
Quoted 6 lines
for non-subscribers. Linus has reverted the offending patch
fd6e732186ab522c812ab19c2c5e5befb8ec8115in question so now the PCI and I/O port code needs to be fixed up to be able to handle such a setup.A test report of this patch which is meant to be applied on top of today's lmo git kernel on a Cobalt would be appreciated.
It breaks all I/O port
device(LCD, tulip, VIA ata)drivers.
Thanks, I'll try to sort this out tonight when I'm hopefully going to have access to an actual machine.
The bootup messages of the failing kernel might be interesting, if you have them at hand.
Ralf
Quoted 8 lines · On Tue, 11 Dec 2007 12:12:20 +0000 Ralf Baechle <[email protected]> wrote:
Some may have been following the beginning of this thread on linux-kernel, see for example
http://www.opensubscriber.com/message/[email protected]/8161812.html
for non-subscribers. Linus has reverted the offending patch
fd6e732186ab522c812ab19c2c5e5befb8ec8115in question so now the PCI and I/O port code needs to be fixed up to be able to handle such a setup.
It can be fixed my fix PCI resource patch.
http://www.linux-mips.org/archives/linux-mips/2007-01/msg00049.html
Yoichi
Quoted 7 lines · Yoichi Yuasa
Quoted 3 lines
for non-subscribers. Linus has reverted the offending patch
fd6e732186ab522c812ab19c2c5e5befb8ec8115in question so now the PCI and I/O port code needs to be fixed up to be able to handle such a setup.It can be fixed my fix PCI resource patch.
http://www.linux-mips.org/archives/linux-mips/2007-01/msg00049.html
Modulo a codying style issue that one is the same as the pci.c segment of the patch I've just posted.
Ralf
Quoted 6 lines · On Tue, 11 Dec 2007 15:35:22 +0000 Ralf Baechle <[email protected]> wrote:
Quoted 4 lines · Yoichi Yuasa
Quoted 3 lines
for non-subscribers. Linus has reverted the offending patch
fd6e732186ab522c812ab19c2c5e5befb8ec8115in question so now the PCI and I/O port code needs to be fixed up to be able to handle such a setup.
Quoted 6 lines
Quoted 3 lines
It can be fixed my fix PCI resource patch.
http://www.linux-mips.org/archives/linux-mips/2007-01/msg00049.html
Modulo a codying style issue that one is the same as the
pci.csegment of the patch I've just posted.
This is a fix proposed before fd6e732186ab522c812ab19c2c5e5befb8ec8115. This patch is still effective.
Fixed line offset and coding style.
arch/mips/pci/pci.c +2 -0
@@ -242,6 +242,8 @@ static void pcibios_fixup_device_resourcfor (i =0 ; i <PCI_NUM_RESOURCES ; i++) {if (!dev->resource[i].start)continue ; +if (dev->resource[i].flags &IORESOURCE_PCI_FIXED ) +continue ;if (dev->resource[i].flags &IORESOURCE_IO ) offset = hose->io_offset;else if (dev->resource[i].flags &IORESOURCE_MEM )
Quoted 6 lines · Yoichi Yuasa
Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
for non-subscribers. Linus has reverted the offending patch
fd6e732186ab522c812ab19c2c5e5befb8ec8115in question so now the PCI and I/O port code needs to be fixed up to be able to handle such a setup.It can be fixed my fix PCI resource patch.
Quoted 7 lines
Quoted 4 lines
Modulo a codying style issue that one is the same as the
pci.csegment of the patch I've just posted.This is a fix proposed before
fd6e732186ab522c812ab19c2c5e5befb8ec8115. This patch is still effective.
Ah, I had already applied the identical patch yesterday. Thanks anyway!
But it should be considered temporary. For some configurations there is no chance for this to work and the patch will probably get in my way for the planned rewrite of the resource allocation.
Ralf