/* fixvideo.c - fix video problem in efi */ /* * VasEBoot -- GRand Unified Bootloader * Copyright (C) 2009 Free Software Foundation, Inc. * * VasEBoot is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VasEBoot is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with VasEBoot. If not, see . */ #include #include #include #include #include #include #include VasEBoot_MOD_LICENSE ("GPLv3+"); static struct VasEBoot_video_patch { const char *name; VasEBoot_uint32_t pci_id; VasEBoot_uint32_t mmio_bar; VasEBoot_uint32_t mmio_reg; VasEBoot_uint32_t mmio_old; } video_patches[] = { {"Intel 945GM", 0x27a28086, 0, 0x71184, 0x1000000}, /* DSPBBASE */ {"Intel 965GM", 0x2a028086, 0, 0x7119C, 0x1000000}, /* DSPBSURF */ {0, 0, 0, 0, 0} }; static int scan_card (VasEBoot_pci_device_t dev, VasEBoot_pci_id_t pciid, void *data __attribute__ ((unused))) { VasEBoot_pci_address_t addr; addr = VasEBoot_pci_make_address (dev, VasEBoot_PCI_REG_CLASS); if (VasEBoot_pci_read_byte (addr + 3) == 0x3) { struct VasEBoot_video_patch *p = video_patches; while (p->name) { if (p->pci_id == pciid) { VasEBoot_addr_t base; VasEBoot_dprintf ("fixvideo", "Found graphic card: %s\n", p->name); addr += 8 + p->mmio_bar * 4; base = VasEBoot_pci_read (addr); if ((! base) || (base & VasEBoot_PCI_ADDR_SPACE_IO) || (base & VasEBoot_PCI_ADDR_MEM_PREFETCH)) VasEBoot_dprintf ("fixvideo", "Invalid MMIO bar %d\n", p->mmio_bar); else { base &= VasEBoot_PCI_ADDR_MEM_MASK; base += p->mmio_reg; if (*((volatile VasEBoot_uint32_t *) base) != p->mmio_old) VasEBoot_dprintf ("fixvideo", "Old value doesn't match\n"); else { *((volatile VasEBoot_uint32_t *) base) = 0; if (*((volatile VasEBoot_uint32_t *) base)) VasEBoot_dprintf ("fixvideo", "Setting MMIO fails\n"); } } return 1; } p++; } VasEBoot_dprintf ("fixvideo", "Unknown graphic card: %x\n", pciid); } return 0; } static VasEBoot_err_t VasEBoot_cmd_fixvideo (VasEBoot_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused))) { VasEBoot_pci_iterate (scan_card, NULL); return 0; } static VasEBoot_command_t cmd_fixvideo; VasEBoot_MOD_INIT(fixvideo) { cmd_fixvideo = VasEBoot_register_command ("fix_video", VasEBoot_cmd_fixvideo, 0, N_("Fix video problem.")); } VasEBoot_MOD_FINI(fixvideo) { VasEBoot_unregister_command (cmd_fixvideo); }