summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames <james.mckenzie@citrix.com>2013-10-23 10:49:44 +0100
committerJames <james.mckenzie@citrix.com>2013-10-23 10:49:44 +0100
commit41d6b314334c3129d27713618271d9b85e6a374d (patch)
treee62919d339cf811f96b73233043afccc15fe33f0
parent25353354795de447538886735c44ccd5765b6204 (diff)
downloadgrub-1.99-pq-41d6b314334c3129d27713618271d9b85e6a374d.tar.gz
grub-1.99-pq-41d6b314334c3129d27713618271d9b85e6a374d.tar.bz2
grub-1.99-pq-41d6b314334c3129d27713618271d9b85e6a374d.zip
first cut at xen
-rw-r--r--master/jmm/xen-multiboot482
-rw-r--r--master/series1
-rw-r--r--master/status53
3 files changed, 536 insertions, 0 deletions
diff --git a/master/jmm/xen-multiboot b/master/jmm/xen-multiboot
new file mode 100644
index 0000000..c2769ec
--- /dev/null
+++ b/master/jmm/xen-multiboot
@@ -0,0 +1,482 @@
+Index: grub2/conf/i386-efi.rmk
+===================================================================
+diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c
+index d9e74b3..9277b0a 100644
+--- a/grub-core/loader/multiboot.c
++++ b/grub-core/loader/multiboot.c
+@@ -42,6 +42,7 @@
+ #include <grub/video.h>
+ #include <grub/memory.h>
+ #include <grub/i18n.h>
++#include <grub/pci.h>
+
+ GRUB_MOD_LICENSE ("GPLv3+");
+
+@@ -51,6 +52,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
+
+ struct grub_relocator *grub_multiboot_relocator = NULL;
+ grub_uint32_t grub_multiboot_payload_eip;
++void *xen_base = NULL;
++
+ #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
+ #define DEFAULT_VIDEO_MODE "text"
+ #else
+@@ -63,6 +66,8 @@ static int console_required;
+ static grub_dl_t my_mod;
+
+
++#include "xen.c"
++
+ /* Return the length of the Multiboot mmap that will be needed to allocate
+ our platform's map. */
+ grub_uint32_t
+@@ -112,6 +117,36 @@ grub_multiboot_set_video_mode (void)
+ }
+
+ static grub_err_t
++grub_xen_boot (void)
++{
++ grub_err_t err;
++ struct grub_relocator32_state state = MULTIBOOT_INITIAL_STATE;
++
++ state.MULTIBOOT_ENTRY_REGISTER = grub_multiboot_payload_eip;
++
++ err = grub_multiboot_make_mbi (&state.MULTIBOOT_MBI_REGISTER);
++
++ if (err)
++ return err;
++
++ xen_setup(xen_base);
++
++ grub_sleep(5);
++
++#ifdef GRUB_MACHINE_EFI
++ err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL);
++ if (err)
++ return err;
++#endif
++
++ grub_relocator32_boot (grub_multiboot_relocator, state);
++
++ /* Not reached. */
++ return GRUB_ERR_NONE;
++}
++
++
++static grub_err_t
+ grub_multiboot_boot (void)
+ {
+ grub_err_t err;
+@@ -213,6 +248,71 @@ grub_multiboot_set_console (int console_type, int accepted_consoles,
+ }
+
+ static grub_err_t
++grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)),
++ int argc, char *argv[])
++{
++ grub_file_t file = 0;
++ grub_err_t err;
++
++ grub_loader_unset ();
++
++ if (argc == 0)
++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
++
++ file = grub_file_open (argv[0]);
++ if (! file)
++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file");
++
++ grub_dl_ref (my_mod);
++
++ /* Skip filename. */
++ grub_multiboot_init_mbi (argc - 1, argv + 1);
++
++ grub_relocator_unload (grub_multiboot_relocator);
++ grub_multiboot_relocator = grub_relocator_new ();
++
++ if (!grub_multiboot_relocator)
++ goto fail;
++
++ err = grub_multiboot_load (file);
++ if (err)
++ goto fail;
++
++ /* God awful hack to find the xen binary in memory */
++ {
++ struct grub_relocator
++ {
++ struct grub_relocator_chunk *chunks;
++ grub_phys_addr_t postchunks;
++ grub_phys_addr_t highestaddr;
++ grub_phys_addr_t highestnonpostaddr;
++ grub_size_t relocators_size;
++ } *gr = (struct grub_relocator *) grub_multiboot_relocator;
++
++
++ xen_base=get_virtual_current_address (gr->chunks);
++ }
++
++ grub_multiboot_set_bootdev ();
++
++ grub_loader_set (grub_xen_boot, grub_multiboot_unload, 0);
++
++ fail:
++ if (file)
++ grub_file_close (file);
++
++ if (grub_errno != GRUB_ERR_NONE)
++ {
++ grub_relocator_unload (grub_multiboot_relocator);
++ grub_multiboot_relocator = NULL;
++ grub_dl_unref (my_mod);
++ }
++
++ return grub_errno;
++}
++
++
++static grub_err_t
+ grub_cmd_multiboot (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+ {
+@@ -329,23 +429,32 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
+ return GRUB_ERR_NONE;;
+ }
+
+-static grub_command_t cmd_multiboot, cmd_module;
++static grub_command_t cmd_multiboot, cmd_module, cmd_xen;
+
+ GRUB_MOD_INIT(multiboot)
+ {
+ cmd_multiboot =
+ #ifdef GRUB_USE_MULTIBOOT2
++
+ grub_register_command ("multiboot2", grub_cmd_multiboot,
+ 0, N_("Load a multiboot 2 kernel."));
+ cmd_module =
+ grub_register_command ("module2", grub_cmd_module,
+ 0, N_("Load a multiboot 2 module."));
++
++ cmd_xen =
++ grub_register_command ("xen2", grub_cmd_xen,
++ 0, N_("Load a multiboot 2 xen kernel."));
+ #else
+ grub_register_command ("multiboot", grub_cmd_multiboot,
+ 0, N_("Load a multiboot kernel."));
+ cmd_module =
+ grub_register_command ("module", grub_cmd_module,
+ 0, N_("Load a multiboot module."));
++
++ cmd_xen =
++ grub_register_command ("xen", grub_cmd_xen,
++ 0, N_("Load a multiboot xen kernel."));
+ #endif
+
+ my_mod = mod;
+diff --git a/grub-core/loader/xen.c b/grub-core/loader/xen.c
+new file mode 100644
+index 0000000..0e3deee
+--- /dev/null
++++ b/grub-core/loader/xen.c
+@@ -0,0 +1,301 @@
++
++#define XEN_EFI_MAGIC 0xdeadbeefef104eadULL
++#define XEN_LOADER_GRUB_64 0x0034365f36387847ULL
++#define XEN_LOADER_GRUB_32 0x0000003233616947ULL
++
++struct xen_efi_hdr
++{
++ grub_uint64_t magic;
++ grub_uint64_t efi_loader_signature;
++ grub_uint64_t efi_system_table_addr;
++ grub_uint64_t realmode_available;
++ grub_uint64_t boot_vid_mode;
++ grub_uint64_t boot_vid_info;
++} __attribute__((packed));
++
++struct xen_boot_video_info {
++ grub_uint8_t orig_x; /* 0x00 */
++ grub_uint8_t orig_y; /* 0x01 */
++ grub_uint8_t orig_video_mode; /* 0x02 */
++ grub_uint8_t orig_video_cols; /* 0x03 */
++ grub_uint8_t orig_video_lines; /* 0x04 */
++ grub_uint8_t orig_video_isVGA; /* 0x05 */
++ grub_uint16_t orig_video_points; /* 0x06 */
++
++ /* VESA graphic mode -- linear frame buffer */
++ grub_uint32_t capabilities; /* 0x08 */
++ grub_uint16_t lfb_linelength; /* 0x0c */
++ grub_uint16_t lfb_width; /* 0x0e */
++ grub_uint16_t lfb_height; /* 0x10 */
++ grub_uint16_t lfb_depth; /* 0x12 */
++ grub_uint32_t lfb_base; /* 0x14 */
++ grub_uint32_t lfb_size; /* 0x18 */
++ grub_uint8_t red_size; /* 0x1c */
++ grub_uint8_t red_pos; /* 0x1d */
++ grub_uint8_t green_size; /* 0x1e */
++ grub_uint8_t green_pos; /* 0x1f */
++ grub_uint8_t blue_size; /* 0x20 */
++ grub_uint8_t blue_pos; /* 0x21 */
++ grub_uint8_t rsvd_size; /* 0x22 */
++ grub_uint8_t rsvd_pos; /* 0x23 */
++ grub_uint16_t vesapm_seg; /* 0x24 */
++ grub_uint16_t vesapm_off; /* 0x26 */
++ grub_uint16_t vesa_attrib; /* 0x28 */
++} __attribute__((packed));
++
++#ifdef GRUB_MACHINE_EFI
++
++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 0x7000
++#define FAKE_SMBIOS_SEG 0x7f00
++
++static void
++inject_bios_acpi (void)
++{
++ unsigned i;
++ void *acpi;
++ grub_uint16_t *ebda_seg_ptr, *low_mem_ptr;
++
++ acpi = 0;
++ for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
++ {
++ grub_efi_guid_t *guid =
++ &grub_efi_system_table->configuration_table[i].vendor_guid;
++
++ if (!grub_memcmp (guid, &acpi2_guid, sizeof (grub_efi_guid_t)))
++ {
++ acpi = grub_efi_system_table->configuration_table[i].vendor_table;
++ grub_printf ("ACPI2: %p\n", acpi);
++ }
++ else if (!grub_memcmp (guid, &acpi_guid, sizeof (grub_efi_guid_t)))
++ {
++ void *t;
++
++ t = grub_efi_system_table->configuration_table[i].vendor_table;
++ if (!acpi)
++ acpi = t;
++ grub_printf ("ACPI: %p\n", t);
++ }
++ }
++
++ if (acpi == 0)
++ return;
++
++ ebda_seg_ptr = (grub_uint16_t *) EBDA_SEG_ADDR;
++ low_mem_ptr = (grub_uint16_t *) LOW_MEM_ADDR;
++
++ *ebda_seg_ptr = FAKE_EBDA_SEG;
++ *low_mem_ptr = FAKE_EBDA_SEG >> 6;
++
++ grub_printf("Copying acpi %p to %x\n",acpi,(int) (FAKE_EBDA_SEG << 4));
++ grub_memcpy ((char *) (FAKE_EBDA_SEG << 4), acpi, 0xf000);
++
++}
++
++static void
++inject_bios_smbios(void)
++{
++ unsigned i;
++ void *smbios;
++
++ smbios = 0;
++ for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
++ {
++ grub_efi_guid_t *guid =
++ &grub_efi_system_table->configuration_table[i].vendor_guid;
++
++ 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 (smbios == 0)
++ return;
++
++ grub_printf("Copying smbios %p to %x\n",smbios,(int) (FAKE_SMBIOS_SEG << 4));
++ grub_memcpy ((char *) (FAKE_SMBIOS_SEG << 4), smbios, 0x1000);
++}
++
++
++static void fake_bios_data(void)
++{
++ inject_bios_smbios();
++ inject_bios_acpi();
++}
++
++#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 0x07: /*firewire*/
++ 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 int
++xen_setup_video (struct xen_boot_video_info *bvi)
++{
++ struct grub_video_mode_info mode_info;
++ void *framebuffer;
++ grub_err_t err;
++ grub_video_driver_id_t driver_id;
++
++ driver_id = grub_video_get_driver_id ();
++
++ if (driver_id == GRUB_VIDEO_DRIVER_NONE)
++ return 1;
++
++ err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
++
++ if (err)
++ {
++ grub_errno = GRUB_ERR_NONE;
++ return 1;
++ }
++
++ bvi->orig_video_isVGA=0x23; /*XXX: what is 0x23? */
++
++ bvi->lfb_linelength=mode_info.pitch;
++ bvi->lfb_width=mode_info.width;
++ bvi->lfb_height=mode_info.height;
++ bvi->lfb_depth=mode_info.bpp;
++
++ bvi->lfb_base=(grub_size_t) framebuffer;
++ bvi->lfb_size=ALIGN_UP ((unsigned int) mode_info.pitch * (unsigned int) mode_info.height, 65536);
++
++ bvi->red_size=mode_info.red_mask_size;
++ bvi->red_pos=mode_info.red_field_pos;
++
++ bvi->green_size=mode_info.green_mask_size;
++ bvi->green_pos=mode_info.green_field_pos;
++
++ bvi->blue_size=mode_info.blue_mask_size;
++ bvi->blue_pos=mode_info.blue_field_pos;
++
++ bvi->rsvd_size=mode_info.reserved_mask_size;
++ bvi->rsvd_pos=mode_info.reserved_field_pos;
++
++ bvi->vesa_attrib=0x3; /*Possible(0x1) and has extended data(0x2)*/
++
++
++ /* No protected mode*/
++ bvi->vesapm_seg=0x0;
++ bvi->vesapm_off=0x0;
++
++ bvi->vesa_attrib=0x1; /*Dac is 8 bit capable*/
++
++
++ return GRUB_ERR_NONE;
++}
++
++
++
++
++static grub_err_t
++xen_setup (grub_uint8_t * base)
++{
++ struct xen_efi_hdr *hdr;
++ grub_uint8_t *realmode_available;
++ grub_uint16_t *boot_vid_mode;
++ grub_uint64_t *efi_system_table_addr;
++ grub_uint64_t *efi_loader_signature;
++ struct xen_boot_video_info *bvi;
++
++ int i;
++
++ for (i = 0; i <0x200; i++)
++ {
++ hdr = (struct xen_efi_hdr *) (base + i);
++ if (hdr->magic == XEN_EFI_MAGIC)
++ break;
++ }
++
++ if (hdr->magic != XEN_EFI_MAGIC)
++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "No EFI support in hypervisor");
++
++ grub_printf("base addr is %p\n",base);
++
++ realmode_available=(grub_uint8_t *)hdr->realmode_available;
++ grub_printf("realmode_available was %x@%p\n",(int) *realmode_available,realmode_available);
++ *realmode_available=0;
++
++ efi_loader_signature=(grub_uint64_t*)hdr->efi_loader_signature;
++
++#if defined(__x86_64__)
++ *efi_loader_signature=XEN_LOADER_GRUB_64;
++#elif defined (__i386__)
++ *efi_loader_signature=XEN_LOADER_GRUB_32;
++#else
++ *efi_loader_signature=0;
++#endif
++
++ efi_system_table_addr=(grub_uint64_t*)hdr->efi_system_table_addr;
++
++ grub_printf("efi_system_table_addr was %llx@%p\n",(long long unsigned) *efi_system_table_addr, efi_system_table_addr);
++
++ *efi_system_table_addr= (grub_uint64_t) grub_efi_system_table;
++
++ boot_vid_mode=(grub_uint16_t *)hdr->boot_vid_mode;
++ grub_printf("boot_vid_mode was 0x%x@%p\n",(int) *boot_vid_mode,boot_vid_mode);
++ *boot_vid_mode=0xf00;
++
++ bvi=(struct xen_boot_video_info *)hdr->boot_vid_info;
++ grub_printf("boot_vid_info @%p\n",bvi);
++
++ xen_setup_video (bvi);
++
++ fake_bios_data();
++ stop_dma();
++
++ return GRUB_ERR_NONE;
++}
++
++
++
diff --git a/master/series b/master/series
index 92264d8..c356a8c 100644
--- a/master/series
+++ b/master/series
@@ -51,6 +51,7 @@ jmm/networking-bis
jmm/efi-sni-bis
jmm/copy-acpi-and-dmi-for-mb-kernels
jmm/disable-all-pci-dma-on-boot
+jmm/xen-multiboot
endstop
#
#
diff --git a/master/status b/master/status
index e69de29..3b3541d 100644
--- a/master/status
+++ b/master/status
@@ -0,0 +1,53 @@
+debian/olpc_prefix_hack.patch
+debian/core_in_fs.patch
+debian/dpkg_version_comparison.patch
+debian/grub_legacy_0_based_partitions.patch
+debian/disable_floppies.patch
+debian/grub.cfg_400.patch
+debian/gfxpayload_keep_default.patch
+debian/mkrescue_diet.patch
+debian/mkconfig_skip_dmcrypt.patch
+debian/install_stage2_confusion.patch
+debian/qemu_img_exists.patch
+debian/branch_devmapper.patch
+debian/branch_squash.patch
+debian/branch_longlinuxcmd.patch
+debian/branch_parse-color.patch
+debian/branch_embed-sectors.patch
+debian/branch_fuse.patch
+debian/mkrescue_efi_modules.patch
+debian/mkconfig_loopback.patch
+debian/lazy_stat.patch
+debian/btrfs_stat.patch
+debian/partition_performance.patch
+debian/kfreebsd-9_ada_devices.patch
+debian/gfxterm_background.patch
+debian/zfs_packed_la_array.patch
+debian/xen_replace.patch
+debian/kfreebsd_mfi_devices.patch
+debian/probe_canonicalise.patch
+debian/mkconfig_skip_readme.patch
+debian/kfreebsd_lvm.patch
+debian/zfs_update.patch
+debian/no_libzfs.patch
+debian/xfs_invalid_bmap.patch
+debian/handle_new_autotools.patch
+debian/bash-completion_identifiers.patch
+debian/mkconfig_gnumach.patch
+debian/gcc_4_6_space.patch
+debian/lzo.patch
+debian/fat_uuid.patch
+debian/efiemu_fix.patch
+debian/4k_sectors.patch
+debian/efi_disk_cache.patch
+debian/dirlen.patch
+debian/hurd.patch
+debian/userland-part.patch
+jmm/efi_call_7-bis
+jmm/efi-load-drivers-bis
+jmm/networking-bis
+jmm/efi-sni-bis
+jmm/copy-acpi-and-dmi-for-mb-kernels
+jmm/disable-all-pci-dma-on-boot
+jmm/xen-multiboot
+endstop