int nicintel_init(void) { struct pci_dev *dev = NULL; uintptr_t addr; /* Needed only for PCI accesses on some platforms. * FIXME: Refactor that into get_mem_perms/rget_io_perms/get_pci_perms? */ if (rget_io_perms()) return 1; /* FIXME: BAR2 is not available if the device uses the CardBus function. */ dev = pcidev_init(nics_intel, PCI_BASE_ADDRESS_2); if (!dev) return 1; addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_2); if (!addr) return 1; nicintel_bar = rphysmap("Intel NIC flash", addr, NICINTEL_MEMMAP_SIZE); if (nicintel_bar == ERROR_PTR) return 1; addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0); if (!addr) return 1; nicintel_control_bar = rphysmap("Intel NIC control/status reg", addr, NICINTEL_CONTROL_MEMMAP_SIZE); if (nicintel_control_bar == ERROR_PTR) return 1; /* FIXME: This register is pretty undocumented in all publicly available * documentation from Intel. Let me quote the complete info we have: * "Flash Control Register: The Flash Control register allows the CPU to * enable writes to an external Flash. The Flash Control Register is a * 32-bit field that allows access to an external Flash device." * Ah yes, we also know where it is, but we have absolutely _no_ idea * what we should do with it. Write 0x0001 because we have nothing * better to do with our time. */ pci_rmmio_writew(0x0001, nicintel_control_bar + CSR_FCR); max_rom_decode.parallel = NICINTEL_MEMMAP_SIZE; register_par_programmer(&par_programmer_nicintel, BUS_PARALLEL); return 0; }
int drkaiser_init(void) { struct pci_dev *dev = NULL; uint32_t addr; if (rget_io_perms()) return 1; dev = pcidev_init(drkaiser_pcidev, PCI_BASE_ADDRESS_2); if (!dev) return 1; addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_2); if (!addr) return 1; /* Write magic register to enable flash write. */ rpci_write_word(dev, PCI_MAGIC_DRKAISER_ADDR, PCI_MAGIC_DRKAISER_VALUE); /* Map 128kB flash memory window. */ drkaiser_bar = rphysmap("Dr. Kaiser PC-Waechter flash memory", addr, DRKAISER_MEMMAP_SIZE); if (drkaiser_bar == ERROR_PTR) return 1; max_rom_decode.parallel = 128 * 1024; register_par_master(&par_master_drkaiser, BUS_PARALLEL); return 0; }
int ogp_spi_init(void) { struct pci_dev *dev = NULL; char *type; type = extract_programmer_param("rom"); if (!type) { msg_perr("Please use flashrom -p ogp_spi:rom=... to specify " "which flashchip you want to access.\n"); return 1; } else if (!strcasecmp(type, "bprom") || !strcasecmp(type, "bios")) { ogp_reg_sel = OGA1_XP10_BPROM_REG_SEL; ogp_reg_siso = OGA1_XP10_BPROM_SI; ogp_reg__ce = OGA1_XP10_BPROM_CE_BAR; ogp_reg_sck = OGA1_XP10_BPROM_SCK; } else if (!strcasecmp(type, "cprom") || !strcasecmp(type, "s3")) { ogp_reg_sel = OGA1_XP10_CPROM_REG_SEL; ogp_reg_siso = OGA1_XP10_CPROM_SI; ogp_reg__ce = OGA1_XP10_CPROM_CE_BAR; ogp_reg_sck = OGA1_XP10_CPROM_SCK; } else { msg_perr("Invalid or missing rom= parameter.\n"); free(type); return 1; } free(type); if (rget_io_perms()) return 1; dev = pcidev_init(ogp_spi, PCI_BASE_ADDRESS_0); if (!dev) return 1; uint32_t io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0); if (!io_base_addr) return 1; ogp_spibar = rphysmap("OGP registers", io_base_addr, 4096); if (ogp_spibar == ERROR_PTR) return 1; if (register_spi_bitbang_master(&bitbang_spi_master_ogp)) return 1; return 0; }
int mcp6x_spi_init(int want_spi) { uint16_t status; uint32_t mcp6x_spibaraddr; struct pci_dev *smbusdev; /* Look for the SMBus device (SMBus PCI class) */ smbusdev = pci_dev_find_vendorclass(0x10de, 0x0c05); if (!smbusdev) { if (want_spi) { msg_perr("ERROR: SMBus device not found. Not enabling " "SPI.\n"); return 1; } else { msg_pinfo("Odd. SMBus device not found.\n"); return 0; } } msg_pdbg("Found SMBus device %04x:%04x at %02x:%02x:%01x\n", smbusdev->vendor_id, smbusdev->device_id, smbusdev->bus, smbusdev->dev, smbusdev->func); /* Locate the BAR where the SPI interface lives. */ mcp6x_spibaraddr = pci_read_long(smbusdev, 0x74); /* BAR size is 64k, bits 15..4 are zero, bit 3..0 declare a * 32-bit non-prefetchable memory BAR. */ mcp6x_spibaraddr &= ~0xffff; msg_pdbg("MCP SPI BAR is at 0x%08x\n", mcp6x_spibaraddr); /* Accessing a NULL pointer BAR is evil. Don't do it. */ if (!mcp6x_spibaraddr && want_spi) { msg_perr("Error: Chipset is strapped for SPI, but MCP SPI BAR is invalid.\n"); return 1; } else if (!mcp6x_spibaraddr && !want_spi) { msg_pdbg("MCP SPI is not used.\n"); return 0; } else if (mcp6x_spibaraddr && !want_spi) { msg_pdbg("Strange. MCP SPI BAR is valid, but chipset apparently doesn't have SPI enabled.\n"); /* FIXME: Should we enable SPI anyway? */ return 0; } /* Map the BAR. Bytewise/wordwise access at 0x530 and 0x540. */ mcp6x_spibar = rphysmap("NVIDIA MCP6x SPI", mcp6x_spibaraddr, 0x544); if (mcp6x_spibar == ERROR_PTR) return 1; status = mmio_readw(mcp6x_spibar + 0x530); msg_pdbg("SPI control is 0x%04x, req=%i, gnt=%i\n", status, (status >> MCP6X_SPI_REQUEST) & 0x1, (status >> MCP6X_SPI_GRANT) & 0x1); mcp_gpiostate = status & 0xff; if (bitbang_spi_init(&bitbang_spi_master_mcp6x)) { /* This should never happen. */ msg_perr("MCP6X bitbang SPI master init failed!\n"); return 1; } return 0; }