diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c | 82 |
1 files changed, 18 insertions, 64 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c index aad482fe7601..1bbc49677107 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c @@ -28,7 +28,6 @@ #include <subdev/bios/image.h> struct shadow { - struct nvkm_oclass base; u32 skip; const struct nvbios_source *func; void *data; @@ -37,9 +36,8 @@ struct shadow { }; static bool -shadow_fetch(struct nvkm_bios *bios, u32 upto) +shadow_fetch(struct nvkm_bios *bios, struct shadow *mthd, u32 upto) { - struct shadow *mthd = (void *)nv_object(bios)->oclass; const u32 limit = (upto + 3) & ~3; const u32 start = bios->size; void *data = mthd->data; @@ -50,50 +48,18 @@ shadow_fetch(struct nvkm_bios *bios, u32 upto) return bios->size >= limit; } -static u8 -shadow_rd08(struct nvkm_object *object, u64 addr) -{ - struct nvkm_bios *bios = (void *)object; - if (shadow_fetch(bios, addr + 1)) - return bios->data[addr]; - return 0x00; -} - -static u16 -shadow_rd16(struct nvkm_object *object, u64 addr) -{ - struct nvkm_bios *bios = (void *)object; - if (shadow_fetch(bios, addr + 2)) - return get_unaligned_le16(&bios->data[addr]); - return 0x0000; -} - -static u32 -shadow_rd32(struct nvkm_object *object, u64 addr) -{ - struct nvkm_bios *bios = (void *)object; - if (shadow_fetch(bios, addr + 4)) - return get_unaligned_le32(&bios->data[addr]); - return 0x00000000; -} - -static struct nvkm_oclass -shadow_class = { - .handle = NV_SUBDEV(VBIOS, 0x00), - .ofuncs = &(struct nvkm_ofuncs) { - .rd08 = shadow_rd08, - .rd16 = shadow_rd16, - .rd32 = shadow_rd32, - }, -}; - static int -shadow_image(struct nvkm_bios *bios, int idx, struct shadow *mthd) +shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd) { struct nvkm_subdev *subdev = &bios->subdev; 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 (!nvbios_image(bios, idx, &image)) { nvkm_debug(subdev, "image %d invalid\n", idx); return 0; @@ -101,7 +67,7 @@ shadow_image(struct nvkm_bios *bios, int idx, struct shadow *mthd) nvkm_debug(subdev, "%08x: type %02x, %d bytes\n", image.base, image.type, image.size); - if (!shadow_fetch(bios, image.size)) { + if (!shadow_fetch(bios, mthd, image.size)) { nvkm_debug(subdev, "%08x: fetch failed\n", image.base); return 0; } @@ -124,23 +90,11 @@ shadow_image(struct nvkm_bios *bios, int idx, struct shadow *mthd) } if (!image.last) - score += shadow_image(bios, idx + 1, mthd); + score += shadow_image(bios, idx + 1, offset + image.size, mthd); return score; } static int -shadow_score(struct nvkm_bios *bios, struct shadow *mthd) -{ - struct nvkm_oclass *oclass = nv_object(bios)->oclass; - int score; - nv_object(bios)->oclass = &mthd->base; - score = shadow_image(bios, 0, mthd); - nv_object(bios)->oclass = oclass; - return score; - -} - -static int shadow_method(struct nvkm_bios *bios, struct shadow *mthd, const char *name) { const struct nvbios_source *func = mthd->func; @@ -154,7 +108,7 @@ shadow_method(struct nvkm_bios *bios, struct shadow *mthd, const char *name) return 0; } } - mthd->score = shadow_score(bios, mthd); + mthd->score = shadow_image(bios, 0, 0, mthd); if (func->fini) func->fini(mthd->data); nvkm_debug(subdev, "scored %d\n", mthd->score); @@ -203,14 +157,14 @@ nvbios_shadow(struct nvkm_bios *bios) struct nvkm_subdev *subdev = &bios->subdev; struct nvkm_device *device = subdev->device; struct shadow mthds[] = { - { shadow_class, 0, &nvbios_of }, - { shadow_class, 0, &nvbios_ramin }, - { shadow_class, 0, &nvbios_rom }, - { shadow_class, 0, &nvbios_acpi_fast }, - { shadow_class, 4, &nvbios_acpi_slow }, - { shadow_class, 1, &nvbios_pcirom }, - { shadow_class, 1, &nvbios_platform }, - { shadow_class } + { 0, &nvbios_of }, + { 0, &nvbios_ramin }, + { 0, &nvbios_rom }, + { 0, &nvbios_acpi_fast }, + { 4, &nvbios_acpi_slow }, + { 1, &nvbios_pcirom }, + { 1, &nvbios_platform }, + {} }, *mthd, *best = NULL; const char *optarg; char *source; |