1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <commonlib/endian.h>
5 #include <device/device.h>
6 #include <device/pci.h>
7 #include <device/pci_ids.h>
8 #include <device/pci_ops.h>
12 #include <acpi/acpigen.h>
14 /* Rmodules don't like weak symbols. */
15 void __weak
map_oprom_vendev_rev(u32
*vendev
, u8
*rev
) { return; }
16 u32 __weak
map_oprom_vendev(u32 vendev
) { return vendev
; }
18 struct rom_header
*pci_rom_probe(const struct device
*dev
)
20 struct rom_header
*rom_header
= NULL
;
21 struct pci_data
*rom_data
;
22 u8 rev
= pci_read_config8(dev
, PCI_REVISION_ID
);
24 u32 vendev
= (dev
->vendor
<< 16) | dev
->device
;
25 u32 mapped_vendev
= vendev
;
27 /* If the ROM is in flash, then don't check the PCI device for it. */
28 if (CONFIG(CHECK_REV_IN_OPROM_NAME
)) {
29 rom_header
= cbfs_boot_map_optionrom_revision(dev
->vendor
, dev
->device
, rev
);
30 map_oprom_vendev_rev(&mapped_vendev
, &mapped_rev
);
32 rom_header
= cbfs_boot_map_optionrom(dev
->vendor
, dev
->device
);
33 mapped_vendev
= map_oprom_vendev(vendev
);
37 if (CONFIG(CHECK_REV_IN_OPROM_NAME
) &&
38 (vendev
!= mapped_vendev
|| rev
!= mapped_rev
)) {
39 rom_header
= cbfs_boot_map_optionrom_revision(
41 mapped_vendev
& 0xffff, mapped_rev
);
42 } else if (vendev
!= mapped_vendev
) {
43 rom_header
= cbfs_boot_map_optionrom(
45 mapped_vendev
& 0xffff);
50 printk(BIOS_DEBUG
, "In CBFS, ROM address for %s = %p\n",
51 dev_path(dev
), rom_header
);
52 } else if (!CONFIG(ON_DEVICE_ROM_LOAD
)) {
53 printk(BIOS_DEBUG
, "PCI Option ROM loading disabled for %s\n",
57 uintptr_t rom_address
;
59 rom_address
= pci_read_config32(dev
, PCI_ROM_ADDRESS
);
61 if (rom_address
== 0x00000000 || rom_address
== 0xffffffff) {
62 #if CONFIG(CPU_QEMU_X86)
63 if ((dev
->class >> 8) == PCI_CLASS_DISPLAY_VGA
)
64 rom_address
= 0xc0000;
69 /* Enable expansion ROM address decoding. */
70 pci_write_config32(dev
, PCI_ROM_ADDRESS
,
71 rom_address
|PCI_ROM_ADDRESS_ENABLE
);
74 rom_address
&= PCI_ROM_ADDRESS_MASK
;
76 printk(BIOS_DEBUG
, "Option ROM address for %s = %lx\n",
77 dev_path(dev
), (unsigned long)rom_address
);
78 rom_header
= (struct rom_header
*)rom_address
;
81 printk(BIOS_SPEW
, "PCI expansion ROM, signature 0x%04x, "
82 "INIT size 0x%04x, data ptr 0x%04x\n",
83 le32_to_cpu(rom_header
->signature
),
84 rom_header
->size
* 512, le32_to_cpu(rom_header
->data
));
86 if (le32_to_cpu(rom_header
->signature
) != PCI_ROM_HDR
) {
87 printk(BIOS_ERR
, "Incorrect expansion ROM header "
88 "signature %04x\n", le32_to_cpu(rom_header
->signature
));
92 rom_data
= (((void *)rom_header
) + le32_to_cpu(rom_header
->data
));
94 printk(BIOS_SPEW
, "PCI ROM image, vendor ID %04x, device ID %04x,\n",
95 rom_data
->vendor
, rom_data
->device
);
96 /* If the device id is mapped, a mismatch is expected */
97 if ((dev
->vendor
!= rom_data
->vendor
98 || dev
->device
!= rom_data
->device
)
99 && (vendev
== mapped_vendev
)) {
100 printk(BIOS_ERR
, "ID mismatch: vendor ID %04x, "
101 "device ID %04x\n", dev
->vendor
, dev
->device
);
105 printk(BIOS_SPEW
, "PCI ROM image, Class Code %04x%02x, "
106 "Code Type %02x\n", rom_data
->class_hi
, rom_data
->class_lo
,
109 if (dev
->class != ((rom_data
->class_hi
<< 8) | rom_data
->class_lo
)) {
110 printk(BIOS_DEBUG
, "Class Code mismatch ROM %08x, dev %08x\n",
111 (rom_data
->class_hi
<< 8) | rom_data
->class_lo
,
119 static void *pci_ram_image_start
= (void *)PCI_RAM_IMAGE_START
;
121 struct rom_header
*pci_rom_load(struct device
*dev
,
122 struct rom_header
*rom_header
)
124 struct pci_data
* rom_data
;
125 unsigned int rom_size
;
126 unsigned int image_size
=0;
129 /* Get next image. */
130 rom_header
= (struct rom_header
*)((void *) rom_header
133 rom_data
= (struct pci_data
*)((void *) rom_header
134 + le32_to_cpu(rom_header
->data
));
136 image_size
= le32_to_cpu(rom_data
->ilen
) * 512;
137 } while ((rom_data
->type
!= 0) && (rom_data
->indicator
!= 0)); // make sure we got x86 version
139 if (rom_data
->type
!= 0)
142 rom_size
= rom_header
->size
* 512;
145 * We check to see if the device thinks it is a VGA device not
146 * whether the ROM image is for a VGA device because some
147 * devices have a mismatch between the hardware and the ROM.
149 if ((dev
->class >> 8) == PCI_CLASS_DISPLAY_VGA
) {
150 #if !CONFIG(MULTIPLE_VGA_ADAPTERS)
151 extern struct device
*vga_pri
; /* Primary VGA device (device.c). */
152 if (dev
!= vga_pri
) return NULL
; /* Only one VGA supported. */
154 if ((void *)PCI_VGA_RAM_IMAGE_START
!= rom_header
) {
155 printk(BIOS_DEBUG
, "Copying VGA ROM Image from %p to "
156 "0x%x, 0x%x bytes\n", rom_header
,
157 PCI_VGA_RAM_IMAGE_START
, rom_size
);
158 memcpy((void *)PCI_VGA_RAM_IMAGE_START
, rom_header
,
161 return (struct rom_header
*) (PCI_VGA_RAM_IMAGE_START
);
164 printk(BIOS_DEBUG
, "Copying non-VGA ROM image from %p to %p, 0x%x "
165 "bytes\n", rom_header
, pci_ram_image_start
, rom_size
);
167 memcpy(pci_ram_image_start
, rom_header
, rom_size
);
168 pci_ram_image_start
+= rom_size
;
169 return (struct rom_header
*) (pci_ram_image_start
-rom_size
);
173 #if CONFIG(HAVE_ACPI_TABLES)
175 /* VBIOS may be modified after oprom init so use the copy if present. */
176 static struct rom_header
*check_initialized(const struct device
*dev
)
178 struct rom_header
*run_rom
;
179 struct pci_data
*rom_data
;
181 if (!CONFIG(VGA_ROM_RUN
))
184 run_rom
= (struct rom_header
*)(uintptr_t)PCI_VGA_RAM_IMAGE_START
;
185 if (read_le16(&run_rom
->signature
) != PCI_ROM_HDR
)
188 rom_data
= (struct pci_data
*)((u8
*)run_rom
189 + read_le16(&run_rom
->data
));
191 if (read_le32(&rom_data
->signature
) == PCI_DATA_HDR
192 && read_le16(&rom_data
->device
) == dev
->device
193 && read_le16(&rom_data
->vendor
) == dev
->vendor
)
200 pci_rom_acpi_fill_vfct(const struct device
*device
, acpi_vfct_t
*vfct_struct
,
201 unsigned long current
)
203 acpi_vfct_image_hdr_t
*header
= &vfct_struct
->image_hdr
;
204 struct rom_header
*rom
;
206 rom
= check_initialized(device
);
208 rom
= pci_rom_probe(device
);
210 printk(BIOS_ERR
, "pci_rom_acpi_fill_vfct failed\n");
214 printk(BIOS_DEBUG
, " Copying %sVBIOS image from %p\n",
215 rom
== (struct rom_header
*)
216 (uintptr_t)PCI_VGA_RAM_IMAGE_START
?
220 header
->DeviceID
= device
->device
;
221 header
->VendorID
= device
->vendor
;
222 header
->PCIBus
= device
->bus
->secondary
;
223 header
->PCIFunction
= PCI_FUNC(device
->path
.pci
.devfn
);
224 header
->PCIDevice
= PCI_SLOT(device
->path
.pci
.devfn
);
225 header
->ImageLength
= rom
->size
* 512;
226 memcpy((void *)&header
->VbiosContent
, rom
, header
->ImageLength
);
228 vfct_struct
->VBIOSImageOffset
= (size_t)header
- (size_t)vfct_struct
;
230 current
+= header
->ImageLength
;
235 pci_rom_write_acpi_tables(const struct device
*device
, unsigned long current
,
236 struct acpi_rsdp
*rsdp
)
238 /* Only handle VGA devices */
239 if ((device
->class >> 8) != PCI_CLASS_DISPLAY_VGA
)
242 /* Only handle enabled devices */
243 if (!device
->enabled
)
246 /* AMD/ATI uses VFCT */
247 if (device
->vendor
== PCI_VENDOR_ID_ATI
) {
250 current
= ALIGN_UP(current
, 8);
251 vfct
= (acpi_vfct_t
*)current
;
252 acpi_create_vfct(device
, vfct
, pci_rom_acpi_fill_vfct
);
253 if (vfct
->header
.length
) {
254 printk(BIOS_DEBUG
, "ACPI: * VFCT at %lx\n", current
);
255 current
+= vfct
->header
.length
;
256 acpi_add_table(rsdp
, vfct
);
263 void pci_rom_ssdt(const struct device
*device
)
267 /* Only handle display devices */
268 if ((device
->class >> 16) != PCI_BASE_CLASS_DISPLAY
)
271 /* Only handle enabled devices */
272 if (!device
->enabled
)
275 /* Probe for option rom */
276 const struct rom_header
*rom
= pci_rom_probe(device
);
277 if (!rom
|| !rom
->size
) {
278 printk(BIOS_WARNING
, "%s: Missing PCI Option ROM\n",
283 const char *scope
= acpi_device_path(device
);
285 printk(BIOS_ERR
, "%s: Missing ACPI scope\n", dev_path(device
));
289 /* Supports up to four devices. */
290 if ((CBMEM_ID_ROM0
+ ngfx
) > CBMEM_ID_ROM3
) {
291 printk(BIOS_ERR
, "%s: Out of CBMEM IDs.\n", dev_path(device
));
296 const size_t cbrom_length
= rom
->size
* 512;
298 printk(BIOS_ERR
, "%s: ROM has zero length!\n",
303 void *cbrom
= cbmem_add(CBMEM_ID_ROM0
+ ngfx
, cbrom_length
);
305 printk(BIOS_ERR
, "%s: Failed to allocate CBMEM.\n",
309 /* Increment CBMEM id for next device */
312 memcpy(cbrom
, rom
, cbrom_length
);
314 /* write _ROM method */
315 acpigen_write_scope(scope
);
316 acpigen_write_rom(cbrom
, cbrom_length
);
317 acpigen_pop_len(); /* pop scope */