Re: [PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
On Sun, 12 Aug 2007, Linus Torvalds wrote: > On Sun, 12 Aug 2007, Dave Jones wrote: > > > > This does make me wonder, why these weren't caught in -mm ? > > I'm worried that -mm isn't getting a lot of exposure these days. People do > run it, but I wonder how many.. andrew caught it in -mm and reverted it. it crashed his vaio. -dean - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
On Sun, 12 Aug 2007, Dave Jones wrote: > > This does make me wonder, why these weren't caught in -mm ? I'm worried that -mm isn't getting a lot of exposure these days. People do run it, but I wonder how many.. That said, a lot of machines won't ever use MMCFG (especially the old ones - and most of the new ones would run x86-64), so that probably explains at least that one. But the x86-64 alternates code would hit anybody who had the "use rep movs for best performance" code, and I'm surprised that one wasn't caught earlier. X86_FEATURE_REP_GOOD is not uncommon (Core 2 has it). So I assume that one wasn't really in -mm at all. Linus - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
On Sun, Aug 12, 2007 at 12:15:26PM -0700, Linus Torvalds wrote: > Bugs happen, but (a) they should happen during the merge window, not when > we're in stabilization phase and (b) the percentages here were just not > very good. This does make me wonder, why these weren't caught in -mm ? Andrew lines up Andi's quilt series in each run afaik, or was the last patchbombing all stuff that bypassed -mm for some reason? Dave -- http://www.codemonkey.org.uk - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
On Sun, 12 Aug 2007, Andi Kleen wrote: > > > > Damn you, Andi. > > Thanks for the kind words. Should I be impressed by the fact that 16% of your patches caused bootup problems, when we're really close to a -rc3, and *long* past the point where we want to address regressions rather than cause them? I simply want you to be more careful. *Much* more careful. As it is, I end up always being afraid of merging your patch-series (and yes, I should have found this even earlier when reading through the diff rather than after I had already applied it, but I didn't, and we had a broken kernel for a few hours as a result. I didn't see any bug-reports about this one, so hopefully nobody noticed, but it still grates me). Bugs happen, but (a) they should happen during the merge window, not when we're in stabilization phase and (b) the percentages here were just not very good. Linus - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
On Sunday 12 August 2007 11:25, Linus Torvalds wrote: > On Thu, 9 Aug 2007, Andi Kleen wrote: > > Some broken devices have been discovered to require %al/%ax/%eax > > registers for MMIO config space accesses. Modify mmconfig.c to use these > > registers explicitly (rather than modify the global readb/writeb/etc > > inlines). > > > > AK: also changed i386 to always use eax > > AK: moved change to extended space probing to different patch > > AK: reworked with inlines according to Linus' requirements. > > AK: improve comments. > > > > Signed-off-by: dean gaudet <[EMAIL PROTECTED]> > > Signed-off-by: Andi Kleen <[EMAIL PROTECTED]> > > Damn you, Andi. Thanks for the kind words. > You had obviously never actually tested this on x86. Hmm, it booted on my i386 test box but it's possible it didn't use MCFG. > > > --- linux.orig/arch/i386/pci/mmconfig.c > > +++ linux/arch/i386/pci/mmconfig.c > > - writeb(value, mmcfg_virt_addr + reg); > > + mmio_config_writeb(mmcfg_virt_addr, value); > > Notice something missing here? The new code cannot work on any machine > that actually uses mmio cfg. Sigh. Ok I assume you already reverted and I'll send a new one. -Andi - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
On Thu, 9 Aug 2007, Andi Kleen wrote: > > Some broken devices have been discovered to require %al/%ax/%eax registers > for MMIO config space accesses. Modify mmconfig.c to use these registers > explicitly (rather than modify the global readb/writeb/etc inlines). > > AK: also changed i386 to always use eax > AK: moved change to extended space probing to different patch > AK: reworked with inlines according to Linus' requirements. > AK: improve comments. > > Signed-off-by: dean gaudet <[EMAIL PROTECTED]> > Signed-off-by: Andi Kleen <[EMAIL PROTECTED]> Damn you, Andi. You had obviously never actually tested this on x86. > --- linux.orig/arch/i386/pci/mmconfig.c > +++ linux/arch/i386/pci/mmconfig.c > - writeb(value, mmcfg_virt_addr + reg); > + mmio_config_writeb(mmcfg_virt_addr, value); Notice something missing here? The new code cannot work on any machine that actually uses mmio cfg. Linus - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
On Sun, Aug 12, 2007 at 12:15:26PM -0700, Linus Torvalds wrote: Bugs happen, but (a) they should happen during the merge window, not when we're in stabilization phase and (b) the percentages here were just not very good. This does make me wonder, why these weren't caught in -mm ? Andrew lines up Andi's quilt series in each run afaik, or was the last patchbombing all stuff that bypassed -mm for some reason? Dave -- http://www.codemonkey.org.uk - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
On Sun, 12 Aug 2007, Dave Jones wrote: This does make me wonder, why these weren't caught in -mm ? I'm worried that -mm isn't getting a lot of exposure these days. People do run it, but I wonder how many.. That said, a lot of machines won't ever use MMCFG (especially the old ones - and most of the new ones would run x86-64), so that probably explains at least that one. But the x86-64 alternates code would hit anybody who had the use rep movs for best performance code, and I'm surprised that one wasn't caught earlier. X86_FEATURE_REP_GOOD is not uncommon (Core 2 has it). So I assume that one wasn't really in -mm at all. Linus - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
On Sun, 12 Aug 2007, Linus Torvalds wrote: On Sun, 12 Aug 2007, Dave Jones wrote: This does make me wonder, why these weren't caught in -mm ? I'm worried that -mm isn't getting a lot of exposure these days. People do run it, but I wonder how many.. andrew caught it in -mm and reverted it. it crashed his vaio. -dean - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
On Thu, 9 Aug 2007, Andi Kleen wrote: Some broken devices have been discovered to require %al/%ax/%eax registers for MMIO config space accesses. Modify mmconfig.c to use these registers explicitly (rather than modify the global readb/writeb/etc inlines). AK: also changed i386 to always use eax AK: moved change to extended space probing to different patch AK: reworked with inlines according to Linus' requirements. AK: improve comments. Signed-off-by: dean gaudet [EMAIL PROTECTED] Signed-off-by: Andi Kleen [EMAIL PROTECTED] Damn you, Andi. You had obviously never actually tested this on x86. --- linux.orig/arch/i386/pci/mmconfig.c +++ linux/arch/i386/pci/mmconfig.c - writeb(value, mmcfg_virt_addr + reg); + mmio_config_writeb(mmcfg_virt_addr, value); Notice something missing here? The new code cannot work on any machine that actually uses mmio cfg. Linus - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
On Sunday 12 August 2007 11:25, Linus Torvalds wrote: On Thu, 9 Aug 2007, Andi Kleen wrote: Some broken devices have been discovered to require %al/%ax/%eax registers for MMIO config space accesses. Modify mmconfig.c to use these registers explicitly (rather than modify the global readb/writeb/etc inlines). AK: also changed i386 to always use eax AK: moved change to extended space probing to different patch AK: reworked with inlines according to Linus' requirements. AK: improve comments. Signed-off-by: dean gaudet [EMAIL PROTECTED] Signed-off-by: Andi Kleen [EMAIL PROTECTED] Damn you, Andi. Thanks for the kind words. You had obviously never actually tested this on x86. Hmm, it booted on my i386 test box but it's possible it didn't use MCFG. --- linux.orig/arch/i386/pci/mmconfig.c +++ linux/arch/i386/pci/mmconfig.c - writeb(value, mmcfg_virt_addr + reg); + mmio_config_writeb(mmcfg_virt_addr, value); Notice something missing here? The new code cannot work on any machine that actually uses mmio cfg. Sigh. Ok I assume you already reverted and I'll send a new one. -Andi - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
On Sun, 12 Aug 2007, Andi Kleen wrote: Damn you, Andi. Thanks for the kind words. Should I be impressed by the fact that 16% of your patches caused bootup problems, when we're really close to a -rc3, and *long* past the point where we want to address regressions rather than cause them? I simply want you to be more careful. *Much* more careful. As it is, I end up always being afraid of merging your patch-series (and yes, I should have found this even earlier when reading through the diff rather than after I had already applied it, but I didn't, and we had a broken kernel for a few hours as a result. I didn't see any bug-reports about this one, so hopefully nobody noticed, but it still grates me). Bugs happen, but (a) they should happen during the merge window, not when we're in stabilization phase and (b) the percentages here were just not very good. Linus - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patches] [PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
I was just queuing up an identical patch ;) We didn't run into a problem yet but we were going to fix this to fit our BKDG documentation. I didn't see the original email, could you point me to it? -Joachim On Thursday 09 August 2007 14:41:28 Andi Kleen wrote: > From: dean gaudet <[EMAIL PROTECTED]> > > Some broken devices have been discovered to require %al/%ax/%eax registers > for MMIO config space accesses. Modify mmconfig.c to use these registers > explicitly (rather than modify the global readb/writeb/etc inlines). > > AK: also changed i386 to always use eax > AK: moved change to extended space probing to different patch > AK: reworked with inlines according to Linus' requirements. > AK: improve comments. > > Signed-off-by: dean gaudet <[EMAIL PROTECTED]> > Signed-off-by: Andi Kleen <[EMAIL PROTECTED]> ACKED-by: Joachim Deguara <[EMAIL PROTECTED] > > > --- > arch/i386/pci/mmconfig.c | 14 ++ > arch/i386/pci/pci.h| 43 > +++ arch/x86_64/pci/mmconfig.c | > 12 ++-- > 3 files changed, 55 insertions(+), 14 deletions(-) > > Index: linux/arch/x86_64/pci/mmconfig.c > === > --- linux.orig/arch/x86_64/pci/mmconfig.c > +++ linux/arch/x86_64/pci/mmconfig.c > @@ -66,13 +66,13 @@ static int pci_mmcfg_read(unsigned int s > > switch (len) { > case 1: > - *value = readb(addr + reg); > + *value = mmio_config_readb(addr + reg); > break; > case 2: > - *value = readw(addr + reg); > + *value = mmio_config_readw(addr + reg); > break; > case 4: > - *value = readl(addr + reg); > + *value = mmio_config_readl(addr + reg); > break; > } > > @@ -94,13 +94,13 @@ static int pci_mmcfg_write(unsigned int > > switch (len) { > case 1: > - writeb(value, addr + reg); > + mmio_config_writeb(addr + reg, value); > break; > case 2: > - writew(value, addr + reg); > + mmio_config_writew(addr + reg, value); > break; > case 4: > - writel(value, addr + reg); > + mmio_config_writel(addr + reg, value); > break; > } > > Index: linux/arch/i386/pci/mmconfig.c > === > --- linux.orig/arch/i386/pci/mmconfig.c > +++ linux/arch/i386/pci/mmconfig.c > @@ -82,16 +82,15 @@ static int pci_mmcfg_read(unsigned int s > > switch (len) { > case 1: > - *value = readb(mmcfg_virt_addr + reg); > + *value = mmio_config_readb(mmcfg_virt_addr + reg); > break; > case 2: > - *value = readw(mmcfg_virt_addr + reg); > + *value = mmio_config_readw(mmcfg_virt_addr + reg); > break; > case 4: > - *value = readl(mmcfg_virt_addr + reg); > + *value = mmio_config_readl(mmcfg_virt_addr + reg); > break; > } > - > spin_unlock_irqrestore(_config_lock, flags); > > return 0; > @@ -116,16 +115,15 @@ static int pci_mmcfg_write(unsigned int > > switch (len) { > case 1: > - writeb(value, mmcfg_virt_addr + reg); > + mmio_config_writeb(mmcfg_virt_addr, value); > break; > case 2: > - writew(value, mmcfg_virt_addr + reg); > + mmio_config_writew(mmcfg_virt_addr, value); > break; > case 4: > - writel(value, mmcfg_virt_addr + reg); > + mmio_config_writel(mmcfg_virt_addr, value); > break; > } > - > spin_unlock_irqrestore(_config_lock, flags); > > return 0; > Index: linux/arch/i386/pci/pci.h > === > --- linux.orig/arch/i386/pci/pci.h > +++ linux/arch/i386/pci/pci.h > @@ -104,3 +104,46 @@ extern DECLARE_BITMAP(pci_mmcfg_fallback > extern int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int > bus, unsigned int devfn); > extern int __init pci_mmcfg_arch_init(void); > + > +/* > + * AMD Fam10h CPUs are buggy, and cannot access MMIO config space > + * on their northbrige except through the * %eax register. As such, you > MUST + * NOT use normal IOMEM accesses, you need to only use the magic > mmio-config + * accessor functions. > + * In fact just use pci_config_*, nothing else please. > + */ > +static inline unsigned char mmio_config_readb(void __iomem *pos) > +{ > + u8 val; > + asm volatile("movb (%1),%%al" : "=a" (val) : "r" (pos)); > + return val; > +} > + > +static inline unsigned short mmio_config_readw(void __iomem *pos) > +{ > + u16 val; > + asm volatile("movw (%1),%%ax" : "=a" (val) : "r" (pos)); > + return val; > +} > + > +static inline unsigned int mmio_config_readl(void __iomem *pos) > +{ > + u32
Re: [patches] [PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
I was just queuing up an identical patch ;) We didn't run into a problem yet but we were going to fix this to fit our BKDG documentation. I didn't see the original email, could you point me to it? -Joachim On Thursday 09 August 2007 14:41:28 Andi Kleen wrote: From: dean gaudet [EMAIL PROTECTED] Some broken devices have been discovered to require %al/%ax/%eax registers for MMIO config space accesses. Modify mmconfig.c to use these registers explicitly (rather than modify the global readb/writeb/etc inlines). AK: also changed i386 to always use eax AK: moved change to extended space probing to different patch AK: reworked with inlines according to Linus' requirements. AK: improve comments. Signed-off-by: dean gaudet [EMAIL PROTECTED] Signed-off-by: Andi Kleen [EMAIL PROTECTED] ACKED-by: Joachim Deguara [EMAIL PROTECTED] --- arch/i386/pci/mmconfig.c | 14 ++ arch/i386/pci/pci.h| 43 +++ arch/x86_64/pci/mmconfig.c | 12 ++-- 3 files changed, 55 insertions(+), 14 deletions(-) Index: linux/arch/x86_64/pci/mmconfig.c === --- linux.orig/arch/x86_64/pci/mmconfig.c +++ linux/arch/x86_64/pci/mmconfig.c @@ -66,13 +66,13 @@ static int pci_mmcfg_read(unsigned int s switch (len) { case 1: - *value = readb(addr + reg); + *value = mmio_config_readb(addr + reg); break; case 2: - *value = readw(addr + reg); + *value = mmio_config_readw(addr + reg); break; case 4: - *value = readl(addr + reg); + *value = mmio_config_readl(addr + reg); break; } @@ -94,13 +94,13 @@ static int pci_mmcfg_write(unsigned int switch (len) { case 1: - writeb(value, addr + reg); + mmio_config_writeb(addr + reg, value); break; case 2: - writew(value, addr + reg); + mmio_config_writew(addr + reg, value); break; case 4: - writel(value, addr + reg); + mmio_config_writel(addr + reg, value); break; } Index: linux/arch/i386/pci/mmconfig.c === --- linux.orig/arch/i386/pci/mmconfig.c +++ linux/arch/i386/pci/mmconfig.c @@ -82,16 +82,15 @@ static int pci_mmcfg_read(unsigned int s switch (len) { case 1: - *value = readb(mmcfg_virt_addr + reg); + *value = mmio_config_readb(mmcfg_virt_addr + reg); break; case 2: - *value = readw(mmcfg_virt_addr + reg); + *value = mmio_config_readw(mmcfg_virt_addr + reg); break; case 4: - *value = readl(mmcfg_virt_addr + reg); + *value = mmio_config_readl(mmcfg_virt_addr + reg); break; } - spin_unlock_irqrestore(pci_config_lock, flags); return 0; @@ -116,16 +115,15 @@ static int pci_mmcfg_write(unsigned int switch (len) { case 1: - writeb(value, mmcfg_virt_addr + reg); + mmio_config_writeb(mmcfg_virt_addr, value); break; case 2: - writew(value, mmcfg_virt_addr + reg); + mmio_config_writew(mmcfg_virt_addr, value); break; case 4: - writel(value, mmcfg_virt_addr + reg); + mmio_config_writel(mmcfg_virt_addr, value); break; } - spin_unlock_irqrestore(pci_config_lock, flags); return 0; Index: linux/arch/i386/pci/pci.h === --- linux.orig/arch/i386/pci/pci.h +++ linux/arch/i386/pci/pci.h @@ -104,3 +104,46 @@ extern DECLARE_BITMAP(pci_mmcfg_fallback extern int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus, unsigned int devfn); extern int __init pci_mmcfg_arch_init(void); + +/* + * AMD Fam10h CPUs are buggy, and cannot access MMIO config space + * on their northbrige except through the * %eax register. As such, you MUST + * NOT use normal IOMEM accesses, you need to only use the magic mmio-config + * accessor functions. + * In fact just use pci_config_*, nothing else please. + */ +static inline unsigned char mmio_config_readb(void __iomem *pos) +{ + u8 val; + asm volatile(movb (%1),%%al : =a (val) : r (pos)); + return val; +} + +static inline unsigned short mmio_config_readw(void __iomem *pos) +{ + u16 val; + asm volatile(movw (%1),%%ax : =a (val) : r (pos)); + return val; +} + +static inline unsigned int mmio_config_readl(void __iomem *pos) +{ + u32 val; + asm volatile(movl (%1),%%eax : =a (val) : r (pos)); + return val; +} + +static inline void mmio_config_writeb(void __iomem *pos,
[PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
From: dean gaudet <[EMAIL PROTECTED]> Some broken devices have been discovered to require %al/%ax/%eax registers for MMIO config space accesses. Modify mmconfig.c to use these registers explicitly (rather than modify the global readb/writeb/etc inlines). AK: also changed i386 to always use eax AK: moved change to extended space probing to different patch AK: reworked with inlines according to Linus' requirements. AK: improve comments. Signed-off-by: dean gaudet <[EMAIL PROTECTED]> Signed-off-by: Andi Kleen <[EMAIL PROTECTED]> --- arch/i386/pci/mmconfig.c | 14 ++ arch/i386/pci/pci.h| 43 +++ arch/x86_64/pci/mmconfig.c | 12 ++-- 3 files changed, 55 insertions(+), 14 deletions(-) Index: linux/arch/x86_64/pci/mmconfig.c === --- linux.orig/arch/x86_64/pci/mmconfig.c +++ linux/arch/x86_64/pci/mmconfig.c @@ -66,13 +66,13 @@ static int pci_mmcfg_read(unsigned int s switch (len) { case 1: - *value = readb(addr + reg); + *value = mmio_config_readb(addr + reg); break; case 2: - *value = readw(addr + reg); + *value = mmio_config_readw(addr + reg); break; case 4: - *value = readl(addr + reg); + *value = mmio_config_readl(addr + reg); break; } @@ -94,13 +94,13 @@ static int pci_mmcfg_write(unsigned int switch (len) { case 1: - writeb(value, addr + reg); + mmio_config_writeb(addr + reg, value); break; case 2: - writew(value, addr + reg); + mmio_config_writew(addr + reg, value); break; case 4: - writel(value, addr + reg); + mmio_config_writel(addr + reg, value); break; } Index: linux/arch/i386/pci/mmconfig.c === --- linux.orig/arch/i386/pci/mmconfig.c +++ linux/arch/i386/pci/mmconfig.c @@ -82,16 +82,15 @@ static int pci_mmcfg_read(unsigned int s switch (len) { case 1: - *value = readb(mmcfg_virt_addr + reg); + *value = mmio_config_readb(mmcfg_virt_addr + reg); break; case 2: - *value = readw(mmcfg_virt_addr + reg); + *value = mmio_config_readw(mmcfg_virt_addr + reg); break; case 4: - *value = readl(mmcfg_virt_addr + reg); + *value = mmio_config_readl(mmcfg_virt_addr + reg); break; } - spin_unlock_irqrestore(_config_lock, flags); return 0; @@ -116,16 +115,15 @@ static int pci_mmcfg_write(unsigned int switch (len) { case 1: - writeb(value, mmcfg_virt_addr + reg); + mmio_config_writeb(mmcfg_virt_addr, value); break; case 2: - writew(value, mmcfg_virt_addr + reg); + mmio_config_writew(mmcfg_virt_addr, value); break; case 4: - writel(value, mmcfg_virt_addr + reg); + mmio_config_writel(mmcfg_virt_addr, value); break; } - spin_unlock_irqrestore(_config_lock, flags); return 0; Index: linux/arch/i386/pci/pci.h === --- linux.orig/arch/i386/pci/pci.h +++ linux/arch/i386/pci/pci.h @@ -104,3 +104,46 @@ extern DECLARE_BITMAP(pci_mmcfg_fallback extern int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus, unsigned int devfn); extern int __init pci_mmcfg_arch_init(void); + +/* + * AMD Fam10h CPUs are buggy, and cannot access MMIO config space + * on their northbrige except through the * %eax register. As such, you MUST + * NOT use normal IOMEM accesses, you need to only use the magic mmio-config + * accessor functions. + * In fact just use pci_config_*, nothing else please. + */ +static inline unsigned char mmio_config_readb(void __iomem *pos) +{ + u8 val; + asm volatile("movb (%1),%%al" : "=a" (val) : "r" (pos)); + return val; +} + +static inline unsigned short mmio_config_readw(void __iomem *pos) +{ + u16 val; + asm volatile("movw (%1),%%ax" : "=a" (val) : "r" (pos)); + return val; +} + +static inline unsigned int mmio_config_readl(void __iomem *pos) +{ + u32 val; + asm volatile("movl (%1),%%eax" : "=a" (val) : "r" (pos)); + return val; +} + +static inline void mmio_config_writeb(void __iomem *pos, u8 val) +{ + asm volatile("movb %%al,(%1)" :: "a" (val), "r" (pos) : "memory"); +} + +static inline void mmio_config_writew(void __iomem *pos, u16 val) +{ + asm volatile("movw %%ax,(%1)" :: "a" (val), "r" (pos) :
[PATCH] [1/12] x86: Work around mmio config space quirk on AMD Fam10h
From: dean gaudet [EMAIL PROTECTED] Some broken devices have been discovered to require %al/%ax/%eax registers for MMIO config space accesses. Modify mmconfig.c to use these registers explicitly (rather than modify the global readb/writeb/etc inlines). AK: also changed i386 to always use eax AK: moved change to extended space probing to different patch AK: reworked with inlines according to Linus' requirements. AK: improve comments. Signed-off-by: dean gaudet [EMAIL PROTECTED] Signed-off-by: Andi Kleen [EMAIL PROTECTED] --- arch/i386/pci/mmconfig.c | 14 ++ arch/i386/pci/pci.h| 43 +++ arch/x86_64/pci/mmconfig.c | 12 ++-- 3 files changed, 55 insertions(+), 14 deletions(-) Index: linux/arch/x86_64/pci/mmconfig.c === --- linux.orig/arch/x86_64/pci/mmconfig.c +++ linux/arch/x86_64/pci/mmconfig.c @@ -66,13 +66,13 @@ static int pci_mmcfg_read(unsigned int s switch (len) { case 1: - *value = readb(addr + reg); + *value = mmio_config_readb(addr + reg); break; case 2: - *value = readw(addr + reg); + *value = mmio_config_readw(addr + reg); break; case 4: - *value = readl(addr + reg); + *value = mmio_config_readl(addr + reg); break; } @@ -94,13 +94,13 @@ static int pci_mmcfg_write(unsigned int switch (len) { case 1: - writeb(value, addr + reg); + mmio_config_writeb(addr + reg, value); break; case 2: - writew(value, addr + reg); + mmio_config_writew(addr + reg, value); break; case 4: - writel(value, addr + reg); + mmio_config_writel(addr + reg, value); break; } Index: linux/arch/i386/pci/mmconfig.c === --- linux.orig/arch/i386/pci/mmconfig.c +++ linux/arch/i386/pci/mmconfig.c @@ -82,16 +82,15 @@ static int pci_mmcfg_read(unsigned int s switch (len) { case 1: - *value = readb(mmcfg_virt_addr + reg); + *value = mmio_config_readb(mmcfg_virt_addr + reg); break; case 2: - *value = readw(mmcfg_virt_addr + reg); + *value = mmio_config_readw(mmcfg_virt_addr + reg); break; case 4: - *value = readl(mmcfg_virt_addr + reg); + *value = mmio_config_readl(mmcfg_virt_addr + reg); break; } - spin_unlock_irqrestore(pci_config_lock, flags); return 0; @@ -116,16 +115,15 @@ static int pci_mmcfg_write(unsigned int switch (len) { case 1: - writeb(value, mmcfg_virt_addr + reg); + mmio_config_writeb(mmcfg_virt_addr, value); break; case 2: - writew(value, mmcfg_virt_addr + reg); + mmio_config_writew(mmcfg_virt_addr, value); break; case 4: - writel(value, mmcfg_virt_addr + reg); + mmio_config_writel(mmcfg_virt_addr, value); break; } - spin_unlock_irqrestore(pci_config_lock, flags); return 0; Index: linux/arch/i386/pci/pci.h === --- linux.orig/arch/i386/pci/pci.h +++ linux/arch/i386/pci/pci.h @@ -104,3 +104,46 @@ extern DECLARE_BITMAP(pci_mmcfg_fallback extern int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus, unsigned int devfn); extern int __init pci_mmcfg_arch_init(void); + +/* + * AMD Fam10h CPUs are buggy, and cannot access MMIO config space + * on their northbrige except through the * %eax register. As such, you MUST + * NOT use normal IOMEM accesses, you need to only use the magic mmio-config + * accessor functions. + * In fact just use pci_config_*, nothing else please. + */ +static inline unsigned char mmio_config_readb(void __iomem *pos) +{ + u8 val; + asm volatile(movb (%1),%%al : =a (val) : r (pos)); + return val; +} + +static inline unsigned short mmio_config_readw(void __iomem *pos) +{ + u16 val; + asm volatile(movw (%1),%%ax : =a (val) : r (pos)); + return val; +} + +static inline unsigned int mmio_config_readl(void __iomem *pos) +{ + u32 val; + asm volatile(movl (%1),%%eax : =a (val) : r (pos)); + return val; +} + +static inline void mmio_config_writeb(void __iomem *pos, u8 val) +{ + asm volatile(movb %%al,(%1) :: a (val), r (pos) : memory); +} + +static inline void mmio_config_writew(void __iomem *pos, u16 val) +{ + asm volatile(movw %%ax,(%1) :: a (val), r (pos) : memory); +} + +static inline void