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 void init_pci (void) { auto int NESTED_FUNC_ATTR set_card (grub_pci_device_t dev, grub_pci_id_t pciid); int NESTED_FUNC_ATTR set_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_pci_address_t addr; /* FIXME: autoscan for BARs and devices. */ switch (pciid) { case GRUB_LOONGSON_OHCI_PCIID: addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); grub_pci_write (addr, 0x5025000); addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE | GRUB_PCI_COMMAND_PARITY_ERROR | GRUB_PCI_COMMAND_BUS_MASTER | GRUB_PCI_COMMAND_MEM_ENABLED); addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); grub_pci_write_word (addr, 0x0200 | GRUB_PCI_STATUS_CAPABILITIES); break; case GRUB_LOONGSON_EHCI_PCIID: addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); grub_pci_write (addr, 0x5026000); addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE | GRUB_PCI_COMMAND_PARITY_ERROR | GRUB_PCI_COMMAND_BUS_MASTER | GRUB_PCI_COMMAND_MEM_ENABLED); addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); grub_pci_write_word (addr, (1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT) | GRUB_PCI_STATUS_CAPABILITIES); break; } return 0; }
static int grub_ohci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__((unused)), void *closure __attribute__((unused))) { grub_uint32_t class_code; grub_uint32_t class; grub_uint32_t subclass; grub_uint32_t interf; grub_uint32_t base; grub_pci_address_t addr; struct grub_ohci *o; grub_uint32_t revision; grub_uint32_t frame_interval; addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class_code = grub_pci_read (addr) >> 8; interf = class_code & 0xFF; subclass = (class_code >> 8) & 0xFF; class = class_code >> 16; /* If this is not an OHCI controller, just return. */ if (class != 0x0c || subclass != 0x03 || interf != 0x10) return 0; /* Determine IO base address. */ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); base = grub_pci_read (addr); #if 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; }