Imported Upstream version 3.10
[debian/elilo] / ia32 / sysdeps.h
index d6f33247158c7b3c2c305fb0695d64a58e55bfb1..bb3dc7efd2cb46ea577a6f855ea34cbcec7af584 100644 (file)
 #define __ELILO_SYSDEPS_IA32_H__
 
 #define ELILO_ARCH     "IA-32" /* ASCII string */
+#define PADDR_MASK     0xfffffff
+
+#define INITRD_START   (15*1024*1024)
+#define DEFAULT_KERNEL_START   0x100000
 
 /* for now use library versions */
 #define Memset(a,v,n)  SetMem((a),(n),(v))
  * A new bit, LDRFLAG_BOOT_PARAM_RELOC, in the loader_flags
  * field is also defined in this file.
  */
-typedef struct efi_ia32_boot_params {
-       UINT32 size;
-       UINT32 command_line;
-       UINT32 efi_sys_tbl;
-       UINT32 efi_mem_map;
-       UINT32 efi_mem_map_size;
-       UINT32 efi_mem_desc_size;
-       UINT32 efi_mem_desc_version;
-       UINT32 initrd_start;
-       UINT32 initrd_size;
-       UINT32 loader_start; 
-       UINT32 loader_size;
-       UINT32 kernel_start;
-       UINT32 kernel_size;
-       UINT16 num_cols;        
-       UINT16 num_rows;
-       UINT16 orig_x;
-       UINT16 orig_y;  
-} efi_ia32_boot_params_t;
-
-extern efi_ia32_boot_params_t efi_ia32_bp;
+
 #pragma pack(1)
+
+/* Definitions for converting EFI memory map to E820 map for Linux
+ * These definitions are from include/linux/asm-x86/e820.h
+ * The structure ia32_boot_params below is updated to accommodate E820 map
+ * EFI memory map is converted to E820 map in this structure and passed
+ * to Linux. This way the OS does not need to do the conversion.
+ */
+
+#define E820_RAM        1
+#define E820_RESERVED   2
+#define E820_ACPI       3
+#define E820_NVS        4
+#define E820_MAX       128
+
+struct e820entry {
+       UINT64 addr;    /* start of memory segment */
+       UINT64 size;    /* size of memory segment */
+       UINT32 type;    /* type of memory segment */
+} __attribute__((packed));
+
 typedef union ia32_boot_params {
        UINT8 raw[0x2000];
        struct {
@@ -175,7 +178,7 @@ typedef union ia32_boot_params {
 
 /* EFI boot loader signature. */
 /* 0x1C0 */    UINT8 efi_loader_sig[4];        /* LDR */
-#define EFI_LOADER_SIG         "EFIL"
+#define EFI_LOADER_SIG_IA32            "EL32"
 
 /* Address of the EFI system table. */
 /* 0x1C4 */    UINT32 efi_sys_tbl;             /* LDR */
@@ -197,7 +200,9 @@ typedef union ia32_boot_params {
 /* Available contiguous extended memory in KB. */
 /* 0x1E0 */    UINT32 alt_mem_k;               /* LDR */
 
-/* 0x1E4 */    UINT8 unused_5[0x0D];           /* unused */
+/* 0x1E4 */    UINT32 unused_51;               /* unused */
+/* 0x1E8 */    UINT8  e820_nrmap;
+/* 0x1E9 */    UINT32 unused_52[2];            /* unused */
 
 /* Size of setup code in sectors (1 sector == 512 bytes). */
 /* 0x1F1 */    UINT8 setup_sectors;            /* BLD */
@@ -275,7 +280,11 @@ typedef union ia32_boot_params {
 /* 0x224 */    UINT16 heap_end_ptr;            /* LDR */
 
 /* %%TBD */
-/* 0x226 */    UINT32 base_mem_size;           /* LDR */
+/* 0x226 */    UINT16 unused_7;                /* LDR */
+
+/* 0x228 */    UINT32 cmdline_addr;            /* LDR */
+/* 0x22C */    UINT32 unused_8[41];
+/* 0x2D0 */    UINT8  e820_map[2560];
        } s;
 } boot_params_t;
 #pragma pack()
@@ -293,11 +302,17 @@ typedef union ia32_boot_params {
        UINT8 *t = (UINT8 *)(to); \
        UINT8 *f = (UINT8 *)(from); \
        UINTN n = cnt; \
-       if (t && f && n) { \
-               while (n--) { \
-                       *t++ = *f++; \
-               } \
-       } \
+       if (t && f && n && (t<f)) { \
+               while (n--) { \
+                        *t++ = *f++; \
+                } \
+        } else if (t && f && n && (t>f)) { \
+                t += n; \
+                f += n; \
+                while (n--) { \
+                        *t-- = *f--; \
+                } \
+        } \
 }
 
 #define MEMSET(ptr, size, val) { \
@@ -332,6 +347,7 @@ extern UINTN kernel_size;
 
 extern VOID *initrd_start;
 extern UINTN initrd_size;
+extern VOID *kernel_load_address;
 
 extern dt_addr_t gdt_addr;
 extern dt_addr_t idt_addr;
@@ -351,21 +367,30 @@ extern INTN ia32_use_legacy_free_boot();
 static inline void
 start_kernel(VOID *kentry, boot_params_t *bp)
 {
+       UINT32  temp;
+
        /*
         * Disable interrupts.
         */
-
        asm volatile ( "cli" : : );
 
-       /*
-        * Relocate initrd, if present.
-        */
-
-       if (bp->s.initrd_start) {
-               /* %%TBD */
-               MEMCPY(15 * 1024 * 1024, bp->s.initrd_start, bp->s.initrd_size);
-               bp->s.initrd_start = 15 * 1024 * 1024;
-       }
+        /*
+         * Relocate kernel (if needed), and initrd (if present).
+         * Copy kernel first, in case kernel was loaded overlapping where we're
+         * planning to copy the initrd.  This assumes that the initrd didn't
+         * get loaded overlapping where we're planning to copy the kernel, but
+         * that's pretty unlikely since we couldn't alloc that space for the
+         * kernel (or the kernel would already be there).
+         */
+        if (kernel_start != kernel_load_address) {
+                MEMCPY(kernel_start, kernel_load_address, kernel_size);
+        }
+
+        if (bp->s.initrd_start) {
+                temp =  bp->s.initrd_start;
+                MEMCPY(INITRD_START, temp , bp->s.initrd_size);
+                bp->s.initrd_start = INITRD_START;
+        }
 
        /*
         * Copy boot sector, setup data and command line
@@ -375,20 +400,9 @@ start_kernel(VOID *kentry, boot_params_t *bp)
 
        MEMCPY(high_base_mem, bp, 0x4000);
 
-       /* 
-        * initialize efi ia32 boot params and place them at 1kb up from
-        * the start of the boot command line param.  This results in the 
-        * efi ia32 boot params to be copied to 0x00104c00.  See bootparams.c
-        * for details on how this is arranged.  EFI enabled 
-        * kernels will look for the efi boot params here to know if the
-        * kernel is booting on an EFI platform or legacy BIOS based platfrom
-        */
+       bp = (boot_params_t *)high_base_mem;
+       bp->s.cmdline_addr = high_base_mem + bp->s.cmdline_offset;
 
-       efi_ia32_bp.initrd_start = bp->s.initrd_start;
-       efi_ia32_bp.initrd_size = bp->s.initrd_size;
-
-       MEMCPY(high_base_mem + 0x4000 - 0x0400, &efi_ia32_bp, sizeof(efi_ia32_bp));
        /*
         * Initialize Linux GDT.
         */
@@ -429,7 +443,6 @@ start_kernel(VOID *kentry, boot_params_t *bp)
         * Jump to kernel entry point.
         */
 
-
        asm volatile ( "jmp *%%ecx" : : );
 }