diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index fec513f..81048ef 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -34,6 +34,8 @@ #include #include #include +#include + GRUB_MOD_LICENSE ("GPLv3+"); @@ -495,6 +497,52 @@ static void fake_bios_data(void) #endif +static void stop_dma(void) +{ + + auto int NESTED_FUNC_ATTR stop_card_dma (grub_pci_device_t dev, + grub_pci_id_t pciid); + + int NESTED_FUNC_ATTR stop_card_dma (grub_pci_device_t dev, + grub_pci_id_t pciid) + { + grub_pci_address_t addr; + grub_uint16_t old_cmd,new_cmd; + + (void) pciid; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + + switch (grub_pci_read (addr) >> 24) { + case 0x00: /*unknown*/ + case 0x03: /*GPU*/ + case 0x05: /*memory*/ + case 0x06: /*bridge*/ + case 0x0b: /*cpu*/ + break; + default: /*everything else gets dma turned off*/ + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); + old_cmd = grub_pci_read_word(addr); + new_cmd = old_cmd & ~GRUB_PCI_COMMAND_BUS_MASTER; + grub_pci_write_word(addr,new_cmd); + +#if 0 + if (old_cmd!=new_cmd) { + grub_printf ("Disabled DMA on: %02x:%02x.%x %04x -> %04x\n", + grub_pci_get_bus (dev), grub_pci_get_device (dev), + grub_pci_get_function (dev), (int) old_cmd,(int) new_cmd); + } +#endif + } + + return 0; + } + + grub_pci_iterate (stop_card_dma); +} + + static grub_err_t grub_linux_boot (void) { @@ -642,6 +690,7 @@ grub_linux_boot (void) fake_bios_data(); #endif + #ifdef GRUB_MACHINE_EFI { grub_efi_uintn_t efi_desc_size; @@ -651,7 +700,9 @@ grub_linux_boot (void) &efi_desc_size, &efi_desc_version); if (err) return err; - + + stop_dma(); + /* Note that no boot services are available from here. */ efi_mmap_target = real_mode_target + ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem);