[Nouveau] Loading vbios on OF
Ilia Mirkin
imirkin at alum.mit.edu
Fri Aug 28 02:33:14 PDT 2015
Hey Ben,
So with the following totally-hack-patch below, I get OF to load (but
I have to force it, checksum fails). Of note is the following:
-r--r--r-- 1 root root 2403 Aug 28 09:31
/proc/device-tree/pci at 0,f0000000/NVDA,Parent at 10/NVDA,BMP
I'm not sure why you require the vbios fetches to be multiples of 4
bytes, but that messes things up here. Also I'm not sure where to get
this bios size from in the first place, perhaps we should just add a
->size() callback? Don't all the backends (except pramin) know how
much vbios they have?
diff --git a/drm/nouveau/nvkm/subdev/bios/image.c b/drm/nouveau/nvkm/subdev/bios
/image.c
index 74b14cf..ce0b549 100644
--- a/drm/nouveau/nvkm/subdev/bios/image.c
+++ b/drm/nouveau/nvkm/subdev/bios/image.c
@@ -47,11 +47,17 @@ nvbios_imagen(struct nvkm_bios *bios, struct nvbios_image *i
mage)
return false;
}
- if (!(data = nvbios_pcirTp(bios, image->base, &ver, &hdr, &pcir)))
- return false;
- image->size = pcir.image_size;
- image->type = pcir.image_type;
- image->last = pcir.last;
+ if (!(data = nvbios_pcirTp(bios, image->base, &ver, &hdr, &pcir))) {
+ nvkm_warn(subdev, "PCIR section missing\n");
+ image->size = 2403;
+ image->type = 0;
+ image->last = true;
+ return true;
+ } else {
+ image->size = pcir.image_size;
+ image->type = pcir.image_type;
+ image->last = pcir.last;
+ }
if (image->type != 0x70) {
if (!(data = nvbios_npdeTp(bios, image->base, &npde)))
diff --git a/drm/nouveau/nvkm/subdev/bios/shadow.c
b/drm/nouveau/nvkm/subdev/bios/shadow.c
index 792f017..b7a2249 100644
--- a/drm/nouveau/nvkm/subdev/bios/shadow.c
+++ b/drm/nouveau/nvkm/subdev/bios/shadow.c
@@ -45,7 +45,7 @@ shadow_fetch(struct nvkm_bios *bios, struct shadow
*mthd, u32 upto)
u32 read = mthd->func->read(data, start, limit - start, bios);
bios->size = start + read;
}
- return bios->size >= limit;
+ return bios->size >= upto;
}
static int
@@ -55,7 +55,7 @@ shadow_image(struct nvkm_bios *bios, int idx, u32
offset, struct shadow *mthd)
struct nvbios_image image;
int score = 1;
- if (!shadow_fetch(bios, mthd, offset + 0x1000)) {
+ if (!shadow_fetch(bios, mthd, offset + 0x400)) {
nvkm_debug(subdev, "%08x: header fetch failed\n", offset);
return 0;
}
diff --git a/drm/nouveau/nvkm/subdev/bios/shadowof.c
b/drm/nouveau/nvkm/subdev/bios/shadowof.c
index 29a37f0..066bc1f 100644
--- a/drm/nouveau/nvkm/subdev/bios/shadowof.c
+++ b/drm/nouveau/nvkm/subdev/bios/shadowof.c
@@ -22,6 +22,7 @@
*/
#include "priv.h"
+#include <core/pci.h>
#if defined(__powerpc__)
struct priv {
@@ -33,7 +34,9 @@ static u32
of_read(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
{
struct priv *priv = data;
- if (offset + length <= priv->size) {
+printk(KERN_ERR "offset: %d, length: %d, size: %d\n", offset, length,
priv->size);
+ if (offset <= priv->size) {
+ length = min_t(u32, length, priv->size - offset);
memcpy_fromio(bios->data + offset, priv->data + offset, length);
return length;
}
More information about the Nouveau
mailing list