1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <subdev/bios.h>
25#include <subdev/bios/image.h>
26#include <subdev/bios/pcir.h>
27#include <subdev/bios/npde.h>
28
29static bool
30nvbios_imagen(struct nvkm_bios *bios, struct nvbios_image *image)
31{
32 struct nvkm_subdev *subdev = &bios->subdev;
33 struct nvbios_pcirT pcir;
34 struct nvbios_npdeT npde;
35 u8 ver;
36 u16 hdr;
37 u32 data;
38
39 switch ((data = nvbios_rd16(bios, image->base + 0x00))) {
40 case 0xaa55:
41 case 0xbb77:
42 case 0x4e56:
43 break;
44 default:
45 nvkm_debug(subdev, "%08x: ROM signature (%04x) unknown\n",
46 image->base, data);
47 return false;
48 }
49
50 if (!(data = nvbios_pcirTp(bios, image->base, &ver, &hdr, &pcir)))
51 return false;
52 image->size = pcir.image_size;
53 image->type = pcir.image_type;
54 image->last = pcir.last;
55
56 if (image->type != 0x70) {
57 if (!(data = nvbios_npdeTp(bios, image->base, &npde)))
58 return true;
59 image->size = npde.image_size;
60 image->last = npde.last;
61 } else {
62 image->last = true;
63 }
64
65 return true;
66}
67
68bool
69nvbios_image(struct nvkm_bios *bios, int idx, struct nvbios_image *image)
70{
71 u32 imaged_addr = bios->imaged_addr;
72 memset(image, 0x00, sizeof(*image));
73 bios->imaged_addr = 0;
74 do {
75 image->base += image->size;
76 if (image->last || !nvbios_imagen(bios, image)) {
77 bios->imaged_addr = imaged_addr;
78 return false;
79 }
80 } while(idx--);
81 bios->imaged_addr = imaged_addr;
82 return true;
83}
84