* [PATCH 4/4] vbios/prom: fetch the vbios using only aligned 32-bit accesses
@ 2014-03-25 22:11 Martin Peres
[not found] ` <1395785480-2932-1-git-send-email-martin.peres-GANU6spQydw@public.gmane.org>
0 siblings, 1 reply; 4+ messages in thread
From: Martin Peres @ 2014-03-25 22:11 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
Other kind of accesses are unreliable on Maxwell cards. As advised by NVIDIA,
let's only use 32-bit accesses to fetch the vbios from PROM.
This fixes vbios fetching on my nve7 which failed in certain specific
conditions.
I suggest we Cc stable, for all kernels they still maintain after the big
rewrite.
Suggested-by: Christian Zander <czander-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Martin Peres <martin.peres-GANU6spQydw@public.gmane.org>
---
nvkm/subdev/bios/base.c | 35 +++++++++++++++++++++++------------
1 file changed, 23 insertions(+), 12 deletions(-)
diff --git a/nvkm/subdev/bios/base.c b/nvkm/subdev/bios/base.c
index 5608530..baa5687 100644
--- a/nvkm/subdev/bios/base.c
+++ b/nvkm/subdev/bios/base.c
@@ -157,6 +157,10 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios)
pcireg = 0x001850;
access = nv_mask(bios, pcireg, 0x00000001, 0x00000000);
+ /* WARNING: PROM accesses should always be 32-bits aligned. Other
+ * accesses work on most chipset but do not on Kepler chipsets
+ */
+
/* bail if no rom signature, with a workaround for a PROM reading
* issue on some chipsets. the first read after a period of
* inactivity returns the wrong result, so retry the first header
@@ -164,31 +168,38 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios)
*/
i = 16;
do {
- if (nv_rd08(bios, 0x300000) == 0x55)
+ if ((nv_rd32(bios, 0x300000) & 0xffff) == 0xaa55)
break;
} while (i--);
- if (!i || nv_rd08(bios, 0x300001) != 0xaa)
+ if (!i)
goto out;
- /* additional check (see note below) - read PCI record header */
- pcir = nv_rd08(bios, 0x300018) |
- nv_rd08(bios, 0x300019) << 8;
- if (nv_rd08(bios, 0x300000 + pcir) != 'P' ||
- nv_rd08(bios, 0x300001 + pcir) != 'C' ||
- nv_rd08(bios, 0x300002 + pcir) != 'I' ||
- nv_rd08(bios, 0x300003 + pcir) != 'R')
+ /* check the PCI record header ("PCIR") if its address is aligned */
+ pcir = nv_rd32(bios, 0x300018) & 0xffff;
+ if ((pcir % 4) == 0 && nv_rd32(bios, 0x300000 + pcir) != 0x52494350)
goto out;
/* read entire bios image to system memory */
- bios->size = nv_rd08(bios, 0x300002) * 512;
+ bios->size = ((nv_rd32(bios, 0x300000) >> 16) & 0xff) * 512;
if (!bios->size)
goto out;
bios->data = kmalloc(bios->size, GFP_KERNEL);
if (bios->data) {
- for (i = 0; i < bios->size; i++)
- nv_wo08(bios, i, nv_rd08(bios, 0x300000 + i));
+ for (i = 0; i < bios->size; i+=4)
+ nv_wo32(bios, i, nv_rd32(bios, 0x300000 + i));
+ }
+
+ /* check the PCI record header again, now that we can make
+ * un-aligned accesses
+ */
+ if (bios->data[pcir + 0] != 'P' ||
+ bios->data[pcir + 1] != 'C' ||
+ bios->data[pcir + 2] != 'I' ||
+ bios->data[pcir + 3] != 'R') {
+ bios->size = 0;
+ kfree(bios->data);
}
out:
--
1.9.1
^ permalink raw reply related [flat|nested] 4+ messages in thread[parent not found: <1395785480-2932-1-git-send-email-martin.peres-GANU6spQydw@public.gmane.org>]
* Re: [PATCH 4/4] vbios/prom: fetch the vbios using only aligned 32-bit accesses [not found] ` <1395785480-2932-1-git-send-email-martin.peres-GANU6spQydw@public.gmane.org> @ 2014-03-25 22:24 ` Ilia Mirkin [not found] ` <CAKb7Uvhahzo7S-B63V=tQQK=gbXhV4qv13qbF-ePBOP8d2Ce1g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 0 siblings, 1 reply; 4+ messages in thread From: Ilia Mirkin @ 2014-03-25 22:24 UTC (permalink / raw) To: Martin Peres; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org On Tue, Mar 25, 2014 at 6:11 PM, Martin Peres <martin.peres-GANU6spQydw@public.gmane.org> wrote: > Other kind of accesses are unreliable on Maxwell cards. As advised by NVIDIA, Maxwell or Kepler? > let's only use 32-bit accesses to fetch the vbios from PROM. > > This fixes vbios fetching on my nve7 which failed in certain specific > conditions. > > I suggest we Cc stable, for all kernels they still maintain after the big > rewrite. Just throw in the Cc :) Easier to just have it there than to have to go in and edit the commit description to remove this comment and add the Cc line... > > Suggested-by: Christian Zander <czander-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> > Signed-off-by: Martin Peres <martin.peres-GANU6spQydw@public.gmane.org> > --- > nvkm/subdev/bios/base.c | 35 +++++++++++++++++++++++------------ > 1 file changed, 23 insertions(+), 12 deletions(-) > > diff --git a/nvkm/subdev/bios/base.c b/nvkm/subdev/bios/base.c > index 5608530..baa5687 100644 > --- a/nvkm/subdev/bios/base.c > +++ b/nvkm/subdev/bios/base.c > @@ -157,6 +157,10 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios) > pcireg = 0x001850; > access = nv_mask(bios, pcireg, 0x00000001, 0x00000000); > > + /* WARNING: PROM accesses should always be 32-bits aligned. Other > + * accesses work on most chipset but do not on Kepler chipsets > + */ > + > /* bail if no rom signature, with a workaround for a PROM reading > * issue on some chipsets. the first read after a period of > * inactivity returns the wrong result, so retry the first header > @@ -164,31 +168,38 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios) > */ > i = 16; > do { > - if (nv_rd08(bios, 0x300000) == 0x55) > + if ((nv_rd32(bios, 0x300000) & 0xffff) == 0xaa55) > break; > } while (i--); > > - if (!i || nv_rd08(bios, 0x300001) != 0xaa) > + if (!i) > goto out; > > - /* additional check (see note below) - read PCI record header */ > - pcir = nv_rd08(bios, 0x300018) | > - nv_rd08(bios, 0x300019) << 8; > - if (nv_rd08(bios, 0x300000 + pcir) != 'P' || > - nv_rd08(bios, 0x300001 + pcir) != 'C' || > - nv_rd08(bios, 0x300002 + pcir) != 'I' || > - nv_rd08(bios, 0x300003 + pcir) != 'R') > + /* check the PCI record header ("PCIR") if its address is aligned */ > + pcir = nv_rd32(bios, 0x300018) & 0xffff; > + if ((pcir % 4) == 0 && nv_rd32(bios, 0x300000 + pcir) != 0x52494350) > goto out; So if pcir % 4 != 0, it's all OK? Perhaps you meant if (pcir & 0x3 || nv_rd32(...) != ...) goto out > > /* read entire bios image to system memory */ > - bios->size = nv_rd08(bios, 0x300002) * 512; > + bios->size = ((nv_rd32(bios, 0x300000) >> 16) & 0xff) * 512; You already read this out once, might as well save it. BTW, is CPU endianness affected here? i.e. does nv_rd32 do a le32 -> be32 conversion on a be cpu? I would assume it must since everything assumes that 32-bit reads read in integer values... but then your logic is all wrong, since the bytes are laid out in a different order on be. > if (!bios->size) > goto out; > > bios->data = kmalloc(bios->size, GFP_KERNEL); > if (bios->data) { > - for (i = 0; i < bios->size; i++) > - nv_wo08(bios, i, nv_rd08(bios, 0x300000 + i)); > + for (i = 0; i < bios->size; i+=4) > + nv_wo32(bios, i, nv_rd32(bios, 0x300000 + i)); > + } > + > + /* check the PCI record header again, now that we can make > + * un-aligned accesses Why bother with the two separate mechanisms? In practice, is PCIR ever at a non-mod4 location? (Should be easy to check our bios collection...) > + */ > + if (bios->data[pcir + 0] != 'P' || > + bios->data[pcir + 1] != 'C' || > + bios->data[pcir + 2] != 'I' || > + bios->data[pcir + 3] != 'R') { > + bios->size = 0; > + kfree(bios->data); > } > > out: > -- > 1.9.1 > > _______________________________________________ > Nouveau mailing list > Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org > http://lists.freedesktop.org/mailman/listinfo/nouveau ^ permalink raw reply [flat|nested] 4+ messages in thread
[parent not found: <CAKb7Uvhahzo7S-B63V=tQQK=gbXhV4qv13qbF-ePBOP8d2Ce1g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>]
* Re: [PATCH 4/4] vbios/prom: fetch the vbios using only aligned 32-bit accesses [not found] ` <CAKb7Uvhahzo7S-B63V=tQQK=gbXhV4qv13qbF-ePBOP8d2Ce1g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> @ 2014-03-25 22:30 ` Martin Peres [not found] ` <53320379.7080604-GANU6spQydw@public.gmane.org> 0 siblings, 1 reply; 4+ messages in thread From: Martin Peres @ 2014-03-25 22:30 UTC (permalink / raw) To: Ilia Mirkin; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org On 25/03/2014 23:24, Ilia Mirkin wrote: > On Tue, Mar 25, 2014 at 6:11 PM, Martin Peres <martin.peres-GANU6spQydw@public.gmane.org> wrote: >> Other kind of accesses are unreliable on Maxwell cards. As advised by NVIDIA, > Maxwell or Kepler? Damn, I meant Kepler. I updated the patch in my git tree: http://cgit.freedesktop.org/~mperes/nouveau/commit/?id=661a5c599565686f72e729600b0dd6aa6e472f0c > >> let's only use 32-bit accesses to fetch the vbios from PROM. >> >> This fixes vbios fetching on my nve7 which failed in certain specific >> conditions. >> >> I suggest we Cc stable, for all kernels they still maintain after the big >> rewrite. > Just throw in the Cc :) Easier to just have it there than to have to > go in and edit the commit description to remove this comment and add > the Cc line... I don't want git send-email to send an email to stable, the patch won't apply on any kernel. ^ permalink raw reply [flat|nested] 4+ messages in thread
[parent not found: <53320379.7080604-GANU6spQydw@public.gmane.org>]
* Re: [PATCH 4/4] vbios/prom: fetch the vbios using only aligned 32-bit accesses [not found] ` <53320379.7080604-GANU6spQydw@public.gmane.org> @ 2014-03-25 22:37 ` Ilia Mirkin 0 siblings, 0 replies; 4+ messages in thread From: Ilia Mirkin @ 2014-03-25 22:37 UTC (permalink / raw) To: Martin Peres; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org On Tue, Mar 25, 2014 at 6:30 PM, Martin Peres <martin.peres-GANU6spQydw@public.gmane.org> wrote: > On 25/03/2014 23:24, Ilia Mirkin wrote: >> >> On Tue, Mar 25, 2014 at 6:11 PM, Martin Peres <martin.peres-GANU6spQydw@public.gmane.org> >> wrote: >>> >>> Other kind of accesses are unreliable on Maxwell cards. As advised by >>> NVIDIA, >> >> Maxwell or Kepler? > > > Damn, I meant Kepler. > > I updated the patch in my git tree: > http://cgit.freedesktop.org/~mperes/nouveau/commit/?id=661a5c599565686f72e729600b0dd6aa6e472f0c > >> >>> let's only use 32-bit accesses to fetch the vbios from PROM. >>> >>> This fixes vbios fetching on my nve7 which failed in certain specific >>> conditions. >>> >>> I suggest we Cc stable, for all kernels they still maintain after the big >>> rewrite. >> >> Just throw in the Cc :) Easier to just have it there than to have to >> go in and edit the commit description to remove this comment and add >> the Cc line... > > > I don't want git send-email to send an email to stable, the patch won't > apply on any kernel. > --suppress-cc=bodycc ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-03-25 22:37 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-25 22:11 [PATCH 4/4] vbios/prom: fetch the vbios using only aligned 32-bit accesses Martin Peres
[not found] ` <1395785480-2932-1-git-send-email-martin.peres-GANU6spQydw@public.gmane.org>
2014-03-25 22:24 ` Ilia Mirkin
[not found] ` <CAKb7Uvhahzo7S-B63V=tQQK=gbXhV4qv13qbF-ePBOP8d2Ce1g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-03-25 22:30 ` Martin Peres
[not found] ` <53320379.7080604-GANU6spQydw@public.gmane.org>
2014-03-25 22:37 ` Ilia Mirkin
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.