[Nouveau] [PATCH] bios: fix OF loading

Hans de Goede hdegoede at redhat.com
Fri Oct 2 00:18:54 PDT 2015


Hi,

On 02-10-15 05:41, Ilia Mirkin wrote:

<nothing>

As someone who has recently started following nouveau I must say that
it would greatly help me (and likely others) if patches likes this would
come with a somewhat more descriptive commit message.

Otherwise keep up the good work!

Regards,

Hans


p.s.

I've seen your message on the mesa fire demo on nv34, firing that up now.

> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> ---
>
> Tested on a PowerMac7,3 with a NV34 AGP adapter.
>
>   drm/nouveau/nvkm/subdev/bios/priv.h     |  3 +++
>   drm/nouveau/nvkm/subdev/bios/shadow.c   | 27 ++++++++++++++++++---------
>   drm/nouveau/nvkm/subdev/bios/shadowof.c | 18 ++++++++++++++++--
>   3 files changed, 37 insertions(+), 11 deletions(-)
>
> diff --git a/drm/nouveau/nvkm/subdev/bios/priv.h b/drm/nouveau/nvkm/subdev/bios/priv.h
> index e0ec2a6..212800e 100644
> --- a/drm/nouveau/nvkm/subdev/bios/priv.h
> +++ b/drm/nouveau/nvkm/subdev/bios/priv.h
> @@ -8,7 +8,10 @@ struct nvbios_source {
>   	void *(*init)(struct nvkm_bios *, const char *);
>   	void  (*fini)(void *);
>   	u32   (*read)(void *, u32 offset, u32 length, struct nvkm_bios *);
> +	u32   (*size)(void *);
>   	bool rw;
> +	bool ignore_checksum;
> +	bool no_pcir;
>   };
>
>   int nvbios_extend(struct nvkm_bios *, u32 length);
> diff --git a/drm/nouveau/nvkm/subdev/bios/shadow.c b/drm/nouveau/nvkm/subdev/bios/shadow.c
> index 792f017..b2557e8 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,14 +55,22 @@ 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)) {
> -		nvkm_debug(subdev, "%08x: header fetch failed\n", offset);
> -		return 0;
> -	}
> +	if (mthd->func->no_pcir) {
> +		image.base = 0;
> +		image.type = 0;
> +		image.size = mthd->func->size(mthd->data);
> +		image.last = 1;
> +	} else {
> +		if (!shadow_fetch(bios, mthd, offset + 0x1000)) {
> +			nvkm_debug(subdev, "%08x: header fetch failed\n",
> +				   offset);
> +			return 0;
> +		}
>
> -	if (!nvbios_image(bios, idx, &image)) {
> -		nvkm_debug(subdev, "image %d invalid\n", idx);
> -		return 0;
> +		if (!nvbios_image(bios, idx, &image)) {
> +			nvkm_debug(subdev, "image %d invalid\n", idx);
> +			return 0;
> +		}
>   	}
>   	nvkm_debug(subdev, "%08x: type %02x, %d bytes\n",
>   		   image.base, image.type, image.size);
> @@ -74,7 +82,8 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd)
>
>   	switch (image.type) {
>   	case 0x00:
> -		if (nvbios_checksum(&bios->data[image.base], image.size)) {
> +		if (!mthd->func->ignore_checksum &&
> +		    nvbios_checksum(&bios->data[image.base], image.size)) {
>   			nvkm_debug(subdev, "%08x: checksum failed\n",
>   				   image.base);
>   			if (mthd->func->rw)
> diff --git a/drm/nouveau/nvkm/subdev/bios/shadowof.c b/drm/nouveau/nvkm/subdev/bios/shadowof.c
> index 29a37f0..4a20584 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,17 +34,27 @@ static u32
>   of_read(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
>   {
>   	struct priv *priv = data;
> -	if (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;
>   	}
>   	return 0;
>   }
>
> +static u32
> +of_size(void *data)
> +{
> +	struct priv *priv = data;
> +
> +	return priv->size;
> +}
> +
>   static void *
>   of_init(struct nvkm_bios *bios, const char *name)
>   {
> -	struct pci_dev *pdev = bios->subdev.device->pdev;
> +	struct nvkm_device *device = bios->subdev.device;
> +	struct pci_dev *pdev = device->func->pci(device)->pdev;
>   	struct device_node *dn;
>   	struct priv *priv;
>   	if (!(dn = pci_device_to_OF_node(pdev)))
> @@ -62,7 +73,10 @@ nvbios_of = {
>   	.init = of_init,
>   	.fini = (void(*)(void *))kfree,
>   	.read = of_read,
> +	.size = of_size,
>   	.rw = false,
> +	.ignore_checksum = true,
> +	.no_pcir = true,
>   };
>   #else
>   const struct nvbios_source
>


More information about the Nouveau mailing list