All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] New frame buffer detection algorithm and loadrom command for efi platform
@ 2009-03-21 10:38 Bean
  2009-03-21 15:49 ` step21
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Bean @ 2009-03-21 10:38 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 1241 bytes --]

Hi,

This patch improves the frame buffer detection algorithm. It uses pci
to find the video memory base, then scan it for frame buffer.

It also add a loadrom command which can be used to enable accel
graphic driver. The idea is that you can grab the video bios dump, and
optionally the IVT from pc mode, then load them in efi.

To grab bios dump:
sudo dd if=/dev/mem of=bios.bin bs=65536 skip=12 count=1

You can also include the system bios by changing the count to 4.

To grab IVT dump:
sudo dd if=/dev/mem of=ivt.bin bs=1024 count=1

Then, to load them in grub-efi (ivt.bin is optionally):
loadrom /bios.bin /ivt.bin

Here are some of the findings concerning different video cards:

Old 32-bit efi model, intel card:
Works with intel driver, no need to load vbios or ivt.

New 64-bit efi model, intel card:
Works with intel driver, needs to load vbios.

New 64-bit efi model, nvidia card:
Works with nvidia driver, no needs to load vbios or ivt. However, the
backlight value is set too low so desktop is barely visible. You need
to use a small tool to adjust backlight. The nv driver doesn't work.

New 64-bit efi model, ati radeon card:
Works with fglrx driver, needs to load vbios and ivt. The radeonhd
driver doesn't work.

-- 
Bean

[-- Attachment #2: loadrom.diff --]
[-- Type: application/octet-stream, Size: 18576 bytes --]

diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h
index f4f08ab..996f642 100644
--- a/include/grub/i386/pci.h
+++ b/include/grub/i386/pci.h
@@ -32,4 +32,39 @@ grub_pci_read (grub_pci_address_t addr)
   return grub_inl (GRUB_PCI_DATA_REG);
 }
 
+static inline grub_uint16_t
+grub_pci_read_word (grub_pci_address_t addr)
+{
+  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
+  return grub_inw (GRUB_PCI_DATA_REG + (addr & 3));
+}
+
+static inline grub_uint8_t
+grub_pci_read_byte (grub_pci_address_t addr)
+{
+  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
+  return grub_inb (GRUB_PCI_DATA_REG + (addr & 3));
+}
+
+static inline void
+grub_pci_write (grub_pci_address_t addr, grub_uint32_t data)
+{
+  grub_outl (addr, GRUB_PCI_ADDR_REG);
+  grub_outl (data, GRUB_PCI_DATA_REG);
+}
+
+static inline void
+grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data)
+{
+  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
+  grub_outw (data, GRUB_PCI_DATA_REG + (addr & 3));
+}
+
+static inline void
+grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data)
+{
+  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
+  grub_outb (data, GRUB_PCI_DATA_REG + (addr & 3));
+}
+
 #endif /* GRUB_CPU_PCI_H */
diff --git a/include/grub/pci.h b/include/grub/pci.h
index aceee49..7c8b505 100644
--- a/include/grub/pci.h
+++ b/include/grub/pci.h
@@ -36,8 +36,8 @@
 #define  GRUB_PCI_ADDR_IO_MASK		~0x03
 
 typedef grub_uint32_t grub_pci_id_t;
-typedef int (*grub_pci_iteratefunc_t) (int bus, int device, int func,
-				       grub_pci_id_t pciid);
+typedef int NESTED_FUNC_ATTR (*grub_pci_iteratefunc_t)
+     (int bus, int device, int func, grub_pci_id_t pciid);
 typedef grub_uint32_t grub_pci_address_t;
 
 grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (int bus, int device,
diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c
index c62198a..6e545eb 100644
--- a/loader/i386/efi/linux.c
+++ b/loader/i386/efi/linux.c
@@ -30,6 +30,7 @@
 #include <grub/efi/api.h>
 #include <grub/efi/efi.h>
 #include <grub/efi/uga_draw.h>
+#include <grub/pci.h>
 #include <grub/command.h>
 
 #define GRUB_LINUX_CL_OFFSET		0x1000
@@ -248,9 +249,9 @@ allocate_pages (grub_size_t prot_size)
     }
 
   grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
-                "prot_mode_mem = %lx, prot_mode_pages = %x\n",
-                (unsigned long) real_mode_mem, (unsigned) real_mode_pages,
-                (unsigned long) prot_mode_mem, (unsigned) prot_mode_pages);
+		"prot_mode_mem = %lx, prot_mode_pages = %x\n",
+		(unsigned long) real_mode_mem, (unsigned) real_mode_pages,
+		(unsigned long) prot_mode_mem, (unsigned) prot_mode_pages);
 
   grub_free (mmap);
   return 1;
@@ -263,8 +264,8 @@ allocate_pages (grub_size_t prot_size)
 
 static void
 grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num,
-                      grub_uint64_t start, grub_uint64_t size,
-                      grub_uint32_t type)
+		      grub_uint64_t start, grub_uint64_t size,
+		      grub_uint32_t type)
 {
   int n = *e820_num;
 
@@ -285,19 +286,82 @@ grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num,
 
 static grub_efi_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID;
 static grub_efi_guid_t acpi2_guid = GRUB_EFI_ACPI_20_TABLE_GUID;
+static grub_efi_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID;
 
 #define EBDA_SEG_ADDR	0x40e
 #define LOW_MEM_ADDR	0x413
-#define FAKE_EBDA_SEG	0x9fc0
+#define LOW_MEM_TOP	0xa000
+
+#define BLANK_MEM	0xffffffff
+#define VBIOS_ADDR	0xc0000
+#define SBIOS_ADDR	0xf0000
+
+static int rom_enabled;
+
+static int
+enable_rom_area (void)
+{
+  grub_pci_address_t addr;
+  grub_uint32_t *rom_ptr;
+
+  if (rom_enabled)
+    return 0;
+
+  rom_enabled++;
+
+  rom_ptr = (grub_uint32_t *) VBIOS_ADDR;
+  if (*rom_ptr != BLANK_MEM)
+    {
+      grub_printf ("ROM image present.\n");
+      return 0;
+    }
+
+  addr = grub_pci_make_address (0, 0, 0, 36);
+  grub_pci_write_byte (addr++, 0x30);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr, 0);
+
+  *rom_ptr = 0;
+  if (*rom_ptr != 0)
+    {
+      grub_printf ("Can\'t enable rom area.\n");
+      return 0;
+    }
+
+  return 1;
+}
+
+static void
+lock_rom_area (void)
+{
+  grub_pci_address_t addr;
+
+  addr = grub_pci_make_address (0, 0, 0, 36);
+  grub_pci_write_byte (addr++, 0x10);
+  grub_pci_write_byte (addr++, 0x11);
+  grub_pci_write_byte (addr++, 0x11);
+  grub_pci_write_byte (addr++, 0x11);
+  grub_pci_write_byte (addr, 0x11);
+}
 
 static void
 fake_bios_data (void)
 {
   unsigned i;
-  void *acpi;
+  void *acpi, *smbios;
   grub_uint16_t *ebda_seg_ptr, *low_mem_ptr;
+  char *addr;
+
+  if (*((grub_uint32_t *) SBIOS_ADDR) != BLANK_MEM)
+    return;
 
   acpi = 0;
+  smbios = 0;
   for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
     {
       grub_efi_guid_t *guid =
@@ -317,21 +381,30 @@ fake_bios_data (void)
 	    acpi = t;
 	  grub_printf ("ACPI: %p\n", t);
 	}
+      else if (! grub_memcmp (guid, &smbios_guid, sizeof (grub_efi_guid_t)))
+	{
+	  smbios = grub_efi_system_table->configuration_table[i].vendor_table;
+	  grub_printf ("SMBIOS: %p\n", smbios);
+	}
     }
 
-  if (acpi == 0)
-    return;
-
   ebda_seg_ptr = (grub_uint16_t *) EBDA_SEG_ADDR;
   low_mem_ptr = (grub_uint16_t *) LOW_MEM_ADDR;
+  if ((! *ebda_seg_ptr) && (! *low_mem_ptr))
+    {
+      *ebda_seg_ptr = LOW_MEM_TOP;
+      *low_mem_ptr = (LOW_MEM_TOP >> 6);
+    }
 
-  if ((*ebda_seg_ptr) || (*low_mem_ptr))
-    return;
-
-  *ebda_seg_ptr = FAKE_EBDA_SEG;
-  *low_mem_ptr = FAKE_EBDA_SEG >> 6;
+  addr = (char *) SBIOS_ADDR;
+  if (acpi)
+    {
+      grub_memcpy (addr, acpi, 512);
+      addr += 512;
+    }
 
-  grub_memcpy ((char *) (FAKE_EBDA_SEG << 4), acpi, 1024);
+  if (smbios)
+    grub_memcpy (addr, (char *) smbios + 16, 16);
 }
 
 #ifdef __x86_64__
@@ -353,13 +426,17 @@ grub_linux_boot (void)
   grub_efi_memory_descriptor_t *desc;
   int e820_num;
   
-  fake_bios_data ();
+  if (enable_rom_area ())
+    {
+      fake_bios_data ();
+      lock_rom_area ();
+    }
 
   params = real_mode_mem;
 
   grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n",
 		(unsigned) params->code32_start,
-                (unsigned long) &(idt_desc.limit),
+		(unsigned long) &(idt_desc.limit),
 		(unsigned long) &(gdt_desc.limit));
   grub_dprintf ("linux", "idt = %x:%lx, gdt = %x:%lx\n",
 		(unsigned) idt_desc.limit, (unsigned long) idt_desc.base,
@@ -376,69 +453,69 @@ grub_linux_boot (void)
        desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
     {
       switch (desc->type)
-        {
-        case GRUB_EFI_ACPI_RECLAIM_MEMORY:
-          grub_e820_add_region (params->e820_map, &e820_num,
-                                desc->physical_start,
-                                desc->num_pages << 12,
-                                GRUB_E820_ACPI);
-          break;
-
-        case GRUB_EFI_ACPI_MEMORY_NVS:
-          grub_e820_add_region (params->e820_map, &e820_num,
-                                desc->physical_start,
-                                desc->num_pages << 12,
-                                GRUB_E820_NVS);
-          break;
-
-        case GRUB_EFI_RUNTIME_SERVICES_CODE:
-          grub_e820_add_region (params->e820_map, &e820_num,
-                                desc->physical_start,
-                                desc->num_pages << 12,
-                                GRUB_E820_EXEC_CODE);
-          break;
-
-        case GRUB_EFI_LOADER_CODE:
-        case GRUB_EFI_LOADER_DATA:
-        case GRUB_EFI_BOOT_SERVICES_CODE:
-        case GRUB_EFI_BOOT_SERVICES_DATA:
-        case GRUB_EFI_CONVENTIONAL_MEMORY:
-          {
-            grub_uint64_t start, size, end;
-
-            start = desc->physical_start;
-            size = desc->num_pages << 12;
-            end = start + size;
-
-            /* Skip A0000 - 100000 region.  */
-            if ((start < 0x100000ULL) && (end > 0xA0000ULL))
-              {
-                if (start < 0xA0000ULL)
-                  {
-                    grub_e820_add_region (params->e820_map, &e820_num,
-                                          start,
-                                          0xA0000ULL - start,
-                                          GRUB_E820_RAM);
-                  }
-
-                if (end <= 0x100000ULL)
-                  continue;
-
-                start = 0x100000ULL;
-                size = end - start;
-              }
-
-            grub_e820_add_region (params->e820_map, &e820_num,
-                                  start, size, GRUB_E820_RAM);
-            break;
-          }
-
-        default:
-          grub_e820_add_region (params->e820_map, &e820_num,
-                                desc->physical_start,
-                                desc->num_pages << 12,
-                                GRUB_E820_RESERVED);
-        }
+	{
+	case GRUB_EFI_ACPI_RECLAIM_MEMORY:
+	  grub_e820_add_region (params->e820_map, &e820_num,
+				desc->physical_start,
+				desc->num_pages << 12,
+				GRUB_E820_ACPI);
+	  break;
+
+	case GRUB_EFI_ACPI_MEMORY_NVS:
+	  grub_e820_add_region (params->e820_map, &e820_num,
+				desc->physical_start,
+				desc->num_pages << 12,
+				GRUB_E820_NVS);
+	  break;
+
+	case GRUB_EFI_RUNTIME_SERVICES_CODE:
+	  grub_e820_add_region (params->e820_map, &e820_num,
+				desc->physical_start,
+				desc->num_pages << 12,
+				GRUB_E820_EXEC_CODE);
+	  break;
+
+	case GRUB_EFI_LOADER_CODE:
+	case GRUB_EFI_LOADER_DATA:
+	case GRUB_EFI_BOOT_SERVICES_CODE:
+	case GRUB_EFI_BOOT_SERVICES_DATA:
+	case GRUB_EFI_CONVENTIONAL_MEMORY:
+	  {
+	    grub_uint64_t start, size, end;
+
+	    start = desc->physical_start;
+	    size = desc->num_pages << 12;
+	    end = start + size;
+
+	    /* Skip A0000 - 100000 region.  */
+	    if ((start < 0x100000ULL) && (end > 0xA0000ULL))
+	      {
+		if (start < 0xA0000ULL)
+		  {
+		    grub_e820_add_region (params->e820_map, &e820_num,
+					  start,
+					  0xA0000ULL - start,
+					  GRUB_E820_RAM);
+		  }
+
+		if (end <= 0x100000ULL)
+		  continue;
+
+		start = 0x100000ULL;
+		size = end - start;
+	      }
+
+	    grub_e820_add_region (params->e820_map, &e820_num,
+				  start, size, GRUB_E820_RAM);
+	    break;
+	  }
+
+	default:
+	  grub_e820_add_region (params->e820_map, &e820_num,
+				desc->physical_start,
+				desc->num_pages << 12,
+				GRUB_E820_RESERVED);
+	}
     }
 
   params->mmap_size = e820_num;
@@ -520,41 +597,150 @@ static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
 #define FBTEST_STEP	(0x10000 >> 2)
 #define FBTEST_COUNT	8
 
-static grub_uint32_t fb_list[]=
-  {0x40000000, 0x80000000, 0xc0000000, 0};
+static int
+find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
+{
+  grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base;
+  int i;
+
+  for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP)
+    {
+      if ((*base & RGB_MASK) == RGB_MAGIC)
+	{
+	  int j;
+
+	  for (j = LINE_MIN; j <= LINE_MAX; j++)
+	    {
+	      if ((base[j] & RGB_MASK) == RGB_MAGIC)
+		{
+		  *fb_base = (grub_uint32_t) (grub_target_addr_t) base;
+		  *line_len = j << 2;
+
+		  return 1;
+		}
+	    }
+
+	  break;
+	}
+    }
+
+  return 0;
+}
 
 static int
 find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
 {
-  grub_uint32_t *fb;
+  int found = 0;
+
+  auto int NESTED_FUNC_ATTR find_card (int bus, int dev, int func,
+				       grub_pci_id_t pciid);
 
-  for (fb = fb_list; *fb; fb++)
+  int NESTED_FUNC_ATTR find_card (int bus, int dev, int func,
+				  grub_pci_id_t pciid __attribute__ ((unused)))
     {
-      grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb;
-      int i;
+      grub_pci_address_t addr;
 
-      for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP)
-        {
-	  if ((*base & RGB_MASK) == RGB_MAGIC)
+      addr = grub_pci_make_address (bus, dev, func, 2);
+      if (grub_pci_read (addr) >> 24 == 0x3)
+	{
+	  int i;
+
+	  addr = grub_pci_make_address (bus, dev, func, 4);
+	  for (i = 0; i < 6; i++, addr += 4)
 	    {
-	      int j;
-
-	      for (j = LINE_MIN; j <= LINE_MAX; j++)
-            {
-		  if ((base[j] & RGB_MASK) == RGB_MAGIC)
-                {
-		      *fb_base = (grub_uint32_t) (grub_target_addr_t) base;
-		      *line_len = j << 2;
-
-		      return 0;
-                }
-            }
-
-                break;
-            }
-        }
+	      grub_uint32_t old_bar1, old_bar2, type;
+	      grub_uint64_t base64;
+
+	      old_bar1 = grub_pci_read (addr);
+	      if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
+		continue;
+
+	      type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
+	      if (! (old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH))
+		{
+		  if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+		    {
+		      i++;
+		      addr += 4;
+		    }
+		  continue;
+		}
+
+	      if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+		{
+		  if (i == 5)
+		    break;
+
+		  old_bar2 = grub_pci_read (addr + 4);
+		}
+	      else
+		old_bar2 = 0;
+
+	      base64 = old_bar2;
+	      base64 <<= 32;
+	      base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
+
+	      *fb_base = base64;
+	      if (find_line_len (fb_base, line_len))
+		{
+		  grub_pci_address_t cmd_addr, rom_addr;
+		  grub_uint16_t old_cmd;
+		  grub_uint64_t limit64;
+
+		  cmd_addr = grub_pci_make_address (bus, dev, func, 1);
+		  old_cmd = grub_pci_read_word (cmd_addr);
+
+		  /* Disable mem access.  */
+		  grub_pci_write_word (cmd_addr, old_cmd & 0xfffc);
+
+		  grub_pci_write (addr, 0xffffffff);
+		  if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+		    grub_pci_write (addr + 4, 0xffffffff);
+
+		  if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+		    {
+		      limit64 = grub_pci_read (addr + 4);
+		      limit64 <<= 32;
+		    }
+		  else
+		    limit64 = 0;
+		  limit64 |= (grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK);
+		  limit64 = (~limit64) + 1;
+
+		  /* Restore old state.  */
+		  grub_pci_write (addr, old_bar1);
+		  if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+		    grub_pci_write (addr + 4, old_bar2);
+		  grub_pci_write_word (cmd_addr, old_cmd);
+
+		  grub_printf ("Display controller: %d:%d.%d\n",
+			       bus, dev, func);
+		  grub_printf ("Video memory base: 0x%llx\n",
+			       (unsigned long long) base64);
+		  grub_printf ("Video memory size: 0x%llx\n",
+			       (unsigned long long) limit64);
+
+		  rom_addr = grub_pci_make_address (bus, dev, func, 12);
+		  grub_printf ("Expansion ROM: 0x%x\n",
+			       grub_pci_read (rom_addr));
+
+		  found++;
+		  return 1;
+		}
+
+	      if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+		{
+		  i++;
+		  addr += 4;
+		}
+	    }
+	}
+
+      return 0;
     }
-  return 1;
+
+  grub_pci_iterate (find_card);
+  return found;
 }
 
 static int
@@ -580,13 +766,13 @@ grub_linux_setup_video (struct linux_kernel_params *params)
   ret = find_framebuf (&fb_base, &line_len);
   grub_efi_set_text_mode (1);
 
-  if (ret)
+  if (! ret)
     {
       grub_printf ("Can\'t find frame buffer address\n");
       return 1;
     }
 
-  grub_printf ("Video frame buffer: 0x%x\n", fb_base);
+  grub_printf ("Frame buffer base: 0x%x\n", fb_base);
   grub_printf ("Video line length: %d\n", line_len);
 
   params->lfb_width = width;
@@ -848,16 +1034,16 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
       }
     else if (grub_memcmp (argv[i], "video=", 6) == 0)
       {
-        if (grub_memcmp (&argv[i][6], "vesafb", 6) == 0)
-          video_type = GRUB_VIDEO_TYPE_VLFB;
-        else if (grub_memcmp (&argv[i][6], "efifb", 5) == 0)
-          video_type = GRUB_VIDEO_TYPE_EFI;
+	if (grub_memcmp (&argv[i][6], "vesafb", 6) == 0)
+	  video_type = GRUB_VIDEO_TYPE_VLFB;
+	else if (grub_memcmp (&argv[i][6], "efifb", 5) == 0)
+	  video_type = GRUB_VIDEO_TYPE_EFI;
       }
 
   if (video_type)
     {
       if (!  grub_linux_setup_video (params))
-        params->have_vga = video_type;
+	params->have_vga = video_type;
     }
 
   /* Specify the boot file.  */
@@ -946,7 +1132,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
 
   /* Usually, the compression ratio is about 50%.  */
   addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
-             + page_align (size);
+	     + page_align (size);
   
   /* Find the highest address to put the initrd.  */
   mmap_size = find_mmap_size ();
@@ -968,7 +1154,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
 	    physical_end = addr_max;
 
 	  if (physical_end < page_align (size))
-            continue;
+	    continue;
 
 	  physical_end -= page_align (size);
 
@@ -1009,7 +1195,64 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
   return grub_errno;
 }
 
-static grub_command_t cmd_linux, cmd_initrd;
+static grub_err_t
+grub_cmd_loadrom (grub_command_t cmd __attribute__ ((unused)),
+		  int argc, char *argv[])
+{
+  grub_file_t file;
+  int size;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "No rom image specified");
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    return grub_errno;
+
+  size = file->size;
+  if ((size < 0x10000) || (size > 0x40000))
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid rom image size");
+      goto quit;
+    }
+
+  if (! enable_rom_area ())
+    goto quit;
+
+  do
+    {
+      grub_file_read (file, (char *) VBIOS_ADDR, size);
+      if (grub_errno)
+	break;
+
+      if (argc > 1)
+	{
+	  grub_file_close (file);
+	  file = grub_file_open (argv[1]);
+	  if (! file)
+	    break;
+
+	  size = file->size;
+	  if (size != 1024)
+	    {
+	      grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid ivt size");
+	      break;
+	    }
+
+	  grub_file_read (file, (char *) 0, size);
+	}
+    }
+  while (0);
+
+  fake_bios_data ();
+  lock_rom_area ();
+
+ quit:
+  grub_file_close (file);
+  return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd, cmd_loadrom;
 
 GRUB_MOD_INIT(linux)
 {
@@ -1017,6 +1260,10 @@ GRUB_MOD_INIT(linux)
 				     0, "load linux");
   cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
 				      0, "load initrd");
+  cmd_loadrom = grub_register_command ("loadrom", grub_cmd_loadrom,
+				       "loadrom bios_dump [ivt_dump]",
+				       "load bios rom image");
+
   my_mod = mod;
 }
 
@@ -1024,4 +1271,5 @@ GRUB_MOD_FINI(linux)
 {
   grub_unregister_command (cmd_linux);
   grub_unregister_command (cmd_initrd);
+  grub_unregister_command (cmd_loadrom);
 }

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-04-04  8:08 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-21 10:38 [PATCH] New frame buffer detection algorithm and loadrom command for efi platform Bean
2009-03-21 15:49 ` step21
2009-03-21 16:30   ` Bean
2009-03-21 18:01 ` Robert Millan
2009-03-24 14:16 ` Peter Cros
2009-03-25 15:42   ` Bean
2009-03-26  6:56     ` Bean
2009-03-26 16:09       ` step21
2009-03-26 16:21         ` Bean
2009-04-04  8:08           ` Bean

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.