static void nouveau_bios_shadow_pramin(struct nouveau_bios *bios) { struct nouveau_device *device = nv_device(bios); u64 addr = 0; u32 bar0 = 0; int i; if (device->card_type >= NV_50) { if (device->card_type >= NV_C0 && device->card_type < GM100) { if (nv_rd32(bios, 0x022500) & 0x00000001) return; } else if (device->card_type >= GM100) { if (nv_rd32(bios, 0x021c04) & 0x00000001) return; } addr = nv_rd32(bios, 0x619f04); if (!(addr & 0x00000008)) { nv_debug(bios, "... not enabled\n"); return; } if ( (addr & 0x00000003) != 1) { nv_debug(bios, "... not in vram\n"); return; } addr = (addr & 0xffffff00) << 8; if (!addr) { addr = (u64)nv_rd32(bios, 0x001700) << 16; addr += 0xf0000; } bar0 = nv_mask(bios, 0x001700, 0xffffffff, addr >> 16); } /* bail if no rom signature */ if (nv_rd08(bios, 0x700000) != 0x55 || nv_rd08(bios, 0x700001) != 0xaa) goto out; bios->size = nv_rd08(bios, 0x700002) * 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, 0x700000 + i)); } out: if (device->card_type >= NV_50) nv_wr32(bios, 0x001700, bar0); }
static void nouveau_bios_shadow_prom(struct nouveau_bios *bios) { struct nouveau_device *device = nv_device(bios); u32 pcireg, access; u16 pcir; int i; /* enable access to rom */ if (device->card_type >= NV_50) pcireg = 0x088050; else pcireg = 0x001850; access = nv_mask(bios, pcireg, 0x00000001, 0x00000000); /* 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 * byte a few times before giving up as a workaround */ i = 16; do { if (nv_rd08(bios, 0x300000) == 0x55) break; } while (i--); if (!i || nv_rd08(bios, 0x300001) != 0xaa) 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') goto out; /* read entire bios image to system memory */ bios->size = nv_rd08(bios, 0x300002) * 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)); } out: /* disable access to rom */ nv_wr32(bios, pcireg, access); }
static int nvkm_ioctl_wr(struct nouveau_handle *handle, void *data, u32 size) { struct nouveau_object *object = handle->object; struct nouveau_ofuncs *ofuncs = object->oclass->ofuncs; union { struct nvif_ioctl_wr_v0 v0; } *args = data; int ret; nv_ioctl(object, "wr size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nv_ioctl(object, "wr vers %d size %d addr %016llx data %08x\n", args->v0.version, args->v0.size, args->v0.addr, args->v0.data); switch (args->v0.size) { case 1: if (ret = -ENODEV, ofuncs->wr08) { nv_wo08(object, args->v0.addr, args->v0.data); ret = 0; } break; case 2: if (ret = -ENODEV, ofuncs->wr16) { nv_wo16(object, args->v0.addr, args->v0.data); ret = 0; } break; case 4: if (ret = -ENODEV, ofuncs->wr32) { nv_wo32(object, args->v0.addr, args->v0.data); ret = 0; } break; default: ret = -EINVAL; break; } } return ret; }
static void nouveau_bios_shadow_pramin(struct nouveau_bios *bios) { struct nouveau_device *device = nv_device(bios); u64 addr = 0; u32 bar0 = 0; int i; if (device->card_type >= NV_50) { if ( device->card_type < NV_C0 || !(nv_rd32(bios, 0x022500) & 0x00000001)) addr = (u64)(nv_rd32(bios, 0x619f04) & 0xffffff00) << 8; if (!addr) { addr = (u64)nv_rd32(bios, 0x001700) << 16; addr += 0xf0000; } bar0 = nv_mask(bios, 0x001700, 0xffffffff, addr >> 16); } /* bail if no rom signature */ if (nv_rd08(bios, 0x700000) != 0x55 || nv_rd08(bios, 0x700001) != 0xaa) goto out; bios->size = nv_rd08(bios, 0x700002) * 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, 0x700000 + i)); } out: if (device->card_type >= NV_50) nv_wr32(bios, 0x001700, bar0); }