0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <subdev/bios.h>
0025 #include <subdev/bios/image.h>
0026 #include <subdev/bios/pcir.h>
0027 #include <subdev/bios/npde.h>
0028
0029 static bool
0030 nvbios_imagen(struct nvkm_bios *bios, struct nvbios_image *image)
0031 {
0032 struct nvkm_subdev *subdev = &bios->subdev;
0033 struct nvbios_pcirT pcir;
0034 struct nvbios_npdeT npde;
0035 u8 ver;
0036 u16 hdr;
0037 u32 data;
0038
0039 switch ((data = nvbios_rd16(bios, image->base + 0x00))) {
0040 case 0xaa55:
0041 case 0xbb77:
0042 case 0x4e56:
0043 break;
0044 default:
0045 nvkm_debug(subdev, "%08x: ROM signature (%04x) unknown\n",
0046 image->base, data);
0047 return false;
0048 }
0049
0050 if (!(data = nvbios_pcirTp(bios, image->base, &ver, &hdr, &pcir)))
0051 return false;
0052 image->size = pcir.image_size;
0053 image->type = pcir.image_type;
0054 image->last = pcir.last;
0055
0056 if (image->type != 0x70) {
0057 if (!(data = nvbios_npdeTp(bios, image->base, &npde)))
0058 return true;
0059 image->size = npde.image_size;
0060 image->last = npde.last;
0061 } else {
0062 image->last = true;
0063 }
0064
0065 return true;
0066 }
0067
0068 bool
0069 nvbios_image(struct nvkm_bios *bios, int idx, struct nvbios_image *image)
0070 {
0071 u32 imaged_addr = bios->imaged_addr;
0072 memset(image, 0x00, sizeof(*image));
0073 bios->imaged_addr = 0;
0074 do {
0075 image->base += image->size;
0076 if (image->last || !nvbios_imagen(bios, image)) {
0077 bios->imaged_addr = imaged_addr;
0078 return false;
0079 }
0080 } while(idx--);
0081 bios->imaged_addr = imaged_addr;
0082 return true;
0083 }