1 #include <console/console.h>
2 #include <ip_checksum.h>
4 #include <boot/elf_boot.h>
6 #include <cpu/x86/multiboot.h>
15 #define UPSZ(X) ((sizeof(X) + 3) &~3)
20 unsigned char ft_desc[UPSZ(FIRMWARE_TYPE)];
22 unsigned char bl_desc[UPSZ(BOOTLOADER)];
24 unsigned char blv_desc[UPSZ(BOOTLOADER_VERSION)];
26 unsigned char cmd_desc[UPSZ(CMD_LINE)];
29 .b_signature = 0x0E1FB007,
30 .b_size = sizeof(elf_boot_notes),
36 .n_descsz = sizeof(FIRMWARE_TYPE),
37 .n_type = EBN_FIRMWARE_TYPE,
39 .ft_desc = FIRMWARE_TYPE,
42 .n_descsz = sizeof(BOOTLOADER),
43 .n_type = EBN_BOOTLOADER_NAME,
45 .bl_desc = BOOTLOADER,
48 .n_descsz = sizeof(BOOTLOADER_VERSION),
49 .n_type = EBN_BOOTLOADER_VERSION,
51 .blv_desc = BOOTLOADER_VERSION,
54 .n_descsz = sizeof(CMD_LINE),
55 .n_type = EBN_COMMAND_LINE,
61 int elf_check_arch(Elf_ehdr *ehdr)
64 ((ehdr->e_machine == EM_386) || (ehdr->e_machine == EM_486)) &&
65 (ehdr->e_ident[EI_CLASS] == ELFCLASS32) &&
66 (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
71 void jmp_to_elf_entry(void *entry, unsigned long buffer, unsigned long size)
73 extern unsigned char _ram_seg, _eram_seg;
74 unsigned long lb_start, lb_size;
75 unsigned long adjust, adjusted_boot_notes;
77 elf_boot_notes.hdr.b_checksum =
78 compute_ip_checksum(&elf_boot_notes, sizeof(elf_boot_notes));
80 lb_start = (unsigned long)&_ram_seg;
81 lb_size = (unsigned long)(&_eram_seg - &_ram_seg);
82 adjust = buffer + size - lb_start;
84 adjusted_boot_notes = (unsigned long)&elf_boot_notes;
85 adjusted_boot_notes += adjust;
87 printk(BIOS_SPEW, "entry = 0x%08lx\n", (unsigned long)entry);
88 printk(BIOS_SPEW, "lb_start = 0x%08lx\n", lb_start);
89 printk(BIOS_SPEW, "lb_size = 0x%08lx\n", lb_size);
90 printk(BIOS_SPEW, "adjust = 0x%08lx\n", adjust);
91 printk(BIOS_SPEW, "buffer = 0x%08lx\n", buffer);
92 printk(BIOS_SPEW, " elf_boot_notes = 0x%08lx\n", (unsigned long)&elf_boot_notes);
93 printk(BIOS_SPEW, "adjusted_boot_notes = 0x%08lx\n", adjusted_boot_notes);
98 /* Save the callee save registers... */
102 /* Save the parameters I was passed */
103 " pushl $0\n\t" /* 20 adjust */
104 " pushl %0\n\t" /* 16 lb_start */
105 " pushl %1\n\t" /* 12 buffer */
106 " pushl %2\n\t" /* 8 lb_size */
107 " pushl %3\n\t" /* 4 entry */
108 " pushl %4\n\t" /* 0 elf_boot_notes */
109 /* Compute the adjustment */
110 " xorl %%eax, %%eax\n\t"
111 " subl 16(%%esp), %%eax\n\t"
112 " addl 12(%%esp), %%eax\n\t"
113 " addl 8(%%esp), %%eax\n\t"
114 " movl %%eax, 20(%%esp)\n\t"
115 /* Place a copy of coreboot in its new location */
116 /* Move ``longs'' the coreboot size is 4 byte aligned */
117 " movl 12(%%esp), %%edi\n\t"
118 " addl 8(%%esp), %%edi\n\t"
119 " movl 16(%%esp), %%esi\n\t"
120 " movl 8(%%esp), %%ecx\n\n"
121 " shrl $2, %%ecx\n\t"
124 /* Adjust the stack pointer to point into the new coreboot image */
125 " addl 20(%%esp), %%esp\n\t"
126 /* Adjust the instruction pointer to point into the new coreboot image */
127 " movl $1f, %%eax\n\t"
128 " addl 20(%%esp), %%eax\n\t"
132 /* Copy the coreboot bounce buffer over coreboot */
133 /* Move ``longs'' the coreboot size is 4 byte aligned */
134 " movl 16(%%esp), %%edi\n\t"
135 " movl 12(%%esp), %%esi\n\t"
136 " movl 8(%%esp), %%ecx\n\t"
137 " shrl $2, %%ecx\n\t"
140 /* Now jump to the loaded image */
141 " movl %5, %%eax\n\t"
142 " movl 0(%%esp), %%ebx\n\t"
143 " call *4(%%esp)\n\t"
145 /* The loaded image returned? */
149 /* Copy the saved copy of coreboot where coreboot runs */
150 /* Move ``longs'' the coreboot size is 4 byte aligned */
151 " movl 16(%%esp), %%edi\n\t"
152 " movl 12(%%esp), %%esi\n\t"
153 " addl 8(%%esp), %%esi\n\t"
154 " movl 8(%%esp), %%ecx\n\t"
155 " shrl $2, %%ecx\n\t"
158 /* Adjust the stack pointer to point into the old coreboot image */
159 " subl 20(%%esp), %%esp\n\t"
161 /* Adjust the instruction pointer to point into the old coreboot image */
162 " movl $1f, %%eax\n\t"
163 " subl 20(%%esp), %%eax\n\t"
167 /* Drop the parameters I was passed */
168 " addl $24, %%esp\n\t"
170 /* Restore the callee save registers */
176 "ri" (lb_start), "ri" (buffer), "ri" (lb_size),
179 "ri"(mbi), "ri" (MB_MAGIC2)
181 "ri"(adjusted_boot_notes), "ri" (0x0E1FB007)