static int NESTED_FUNC_ATTR scan_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_pci_address_t addr; addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); if (grub_pci_read_byte (addr + 3) == 0x3) { struct grub_video_patch *p = video_patches; while (p->name) { if (p->pci_id == pciid) { grub_target_addr_t base; grub_printf ("Found graphic card: %s\n", p->name); addr += 8 + p->mmio_bar * 4; base = grub_pci_read (addr); if ((! base) || (base & GRUB_PCI_ADDR_SPACE_IO) || (base & GRUB_PCI_ADDR_MEM_PREFETCH)) grub_printf ("Invalid MMIO bar %d\n", p->mmio_bar); else { base &= GRUB_PCI_ADDR_MEM_MASK; base += p->mmio_reg; if (*((volatile grub_uint32_t *) base) != p->mmio_old) grub_printf ("Old value don't match\n"); else { *((volatile grub_uint32_t *) base) = 0; if (*((volatile grub_uint32_t *) base)) grub_printf ("Set MMIO fails\n"); } } return 1; } p++; } grub_printf ("Unknown graphic card: %x\n", pciid); } return 0; }
static int NESTED_FUNC_ATTR grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_uint32_t regval = 0; grub_pci_address_t addr; if ((pciid & pciid_check_mask) != pciid_check_value) return 0; if (check_bus && grub_pci_get_bus (dev) != bus) return 0; if (check_device && grub_pci_get_device (dev) != device) return 0; if (check_function && grub_pci_get_function (dev) != function) return 0; addr = grub_pci_make_address (dev, regaddr); switch (regsize) { case 1: regval = grub_pci_read_byte (addr); break; case 2: regval = grub_pci_read_word (addr); break; case 4: regval = grub_pci_read (addr); break; } if (varname) { char buf[sizeof ("XXXXXXXX")]; grub_snprintf (buf, sizeof (buf), "%x", regval); grub_env_set (varname, buf); return 1; } if (!write_mask) { grub_printf ("Register %x of %d:%d.%d is %x\n", regaddr, grub_pci_get_bus (dev), grub_pci_get_device (dev), grub_pci_get_function (dev), regval); return 0; } regval = (regval & ~write_mask) | regwrite; switch (regsize) { case 1: grub_pci_write_byte (addr, regval); break; case 2: grub_pci_write_word (addr, regval); break; case 4: grub_pci_write (addr, regval); break; } return 0; }