blob: 1b28a4c50c64fae22607f27da1dd31e21f97b196 [file] [log] [blame]
Eric Biederman8ca8d762003-04-22 19:02:15 +00001#include <console/console.h>
Stefan Reinauere8b08ba2013-05-24 15:09:36 -07002#include <arch/stages.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +00003#include <ip_checksum.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +00004#include <string.h>
Robert Millan81af3d42008-11-11 20:20:54 +00005#include <cpu/x86/multiboot.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +00006
Aaron Durbin8e4a3552013-02-08 17:28:04 -06007#if CONFIG_RELOCATABLE_RAMSTAGE
8/* When the ramstage is relocatable the elf loading ensures an elf image cannot
9 * be loaded over the ramstage code. */
10void jmp_to_elf_entry(void *entry, unsigned long unused1, unsigned long unused2)
11{
Aaron Durbin8e4a3552013-02-08 17:28:04 -060012 /* Jump to kernel */
13 __asm__ __volatile__(
14 " cld \n\t"
15 /* Now jump to the loaded image */
16 " call *%0\n\t"
17
18 /* The loaded image returned? */
19 " cli \n\t"
20 " cld \n\t"
21
22 ::
Aaron Durbin7ae7fc02013-05-28 16:15:01 -050023 "r" (entry)
Aaron Durbin8e4a3552013-02-08 17:28:04 -060024#if CONFIG_MULTIBOOT
Aaron Durbin7ae7fc02013-05-28 16:15:01 -050025 , "b"(mbi), "a" (MB_MAGIC2)
Aaron Durbin8e4a3552013-02-08 17:28:04 -060026#endif
27 );
28}
29#else
Myles Watson92027982009-09-23 20:32:21 +000030void jmp_to_elf_entry(void *entry, unsigned long buffer, unsigned long size)
Eric Biederman8ca8d762003-04-22 19:02:15 +000031{
32 extern unsigned char _ram_seg, _eram_seg;
33 unsigned long lb_start, lb_size;
Eric Biederman8ca8d762003-04-22 19:02:15 +000034
Eric Biederman8ca8d762003-04-22 19:02:15 +000035 lb_start = (unsigned long)&_ram_seg;
36 lb_size = (unsigned long)(&_eram_seg - &_ram_seg);
Eric Biederman8ca8d762003-04-22 19:02:15 +000037
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000038 printk(BIOS_SPEW, "entry = 0x%08lx\n", (unsigned long)entry);
39 printk(BIOS_SPEW, "lb_start = 0x%08lx\n", lb_start);
40 printk(BIOS_SPEW, "lb_size = 0x%08lx\n", lb_size);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000041 printk(BIOS_SPEW, "buffer = 0x%08lx\n", buffer);
Stefan Reinauer14e22772010-04-27 06:56:47 +000042
Eric Biederman8ca8d762003-04-22 19:02:15 +000043 /* Jump to kernel */
44 __asm__ __volatile__(
45 " cld \n\t"
46 /* Save the callee save registers... */
47 " pushl %%esi\n\t"
48 " pushl %%edi\n\t"
49 " pushl %%ebx\n\t"
50 /* Save the parameters I was passed */
51 " pushl $0\n\t" /* 20 adjust */
52 " pushl %0\n\t" /* 16 lb_start */
53 " pushl %1\n\t" /* 12 buffer */
54 " pushl %2\n\t" /* 8 lb_size */
55 " pushl %3\n\t" /* 4 entry */
56 " pushl %4\n\t" /* 0 elf_boot_notes */
57 /* Compute the adjustment */
58 " xorl %%eax, %%eax\n\t"
59 " subl 16(%%esp), %%eax\n\t"
60 " addl 12(%%esp), %%eax\n\t"
61 " addl 8(%%esp), %%eax\n\t"
62 " movl %%eax, 20(%%esp)\n\t"
Stefan Reinauerf834e202009-03-31 17:17:30 +000063 /* Place a copy of coreboot in its new location */
Stefan Reinauerf8ee1802008-01-18 15:08:58 +000064 /* Move ``longs'' the coreboot size is 4 byte aligned */
Eric Biederman8ca8d762003-04-22 19:02:15 +000065 " movl 12(%%esp), %%edi\n\t"
66 " addl 8(%%esp), %%edi\n\t"
67 " movl 16(%%esp), %%esi\n\t"
68 " movl 8(%%esp), %%ecx\n\n"
69 " shrl $2, %%ecx\n\t"
70 " rep movsl\n\t"
71
Stefan Reinauerf8ee1802008-01-18 15:08:58 +000072 /* Adjust the stack pointer to point into the new coreboot image */
Eric Biederman8ca8d762003-04-22 19:02:15 +000073 " addl 20(%%esp), %%esp\n\t"
Stefan Reinauerf8ee1802008-01-18 15:08:58 +000074 /* Adjust the instruction pointer to point into the new coreboot image */
Eric Biederman8ca8d762003-04-22 19:02:15 +000075 " movl $1f, %%eax\n\t"
76 " addl 20(%%esp), %%eax\n\t"
77 " jmp *%%eax\n\t"
78 "1: \n\t"
79
Stefan Reinauerf8ee1802008-01-18 15:08:58 +000080 /* Copy the coreboot bounce buffer over coreboot */
81 /* Move ``longs'' the coreboot size is 4 byte aligned */
Eric Biederman8ca8d762003-04-22 19:02:15 +000082 " movl 16(%%esp), %%edi\n\t"
83 " movl 12(%%esp), %%esi\n\t"
84 " movl 8(%%esp), %%ecx\n\t"
85 " shrl $2, %%ecx\n\t"
86 " rep movsl\n\t"
87
88 /* Now jump to the loaded image */
Robert Millan81af3d42008-11-11 20:20:54 +000089 " movl %5, %%eax\n\t"
Eric Biederman8ca8d762003-04-22 19:02:15 +000090 " movl 0(%%esp), %%ebx\n\t"
91 " call *4(%%esp)\n\t"
92
93 /* The loaded image returned? */
94 " cli \n\t"
95 " cld \n\t"
96
Stefan Reinauerf8ee1802008-01-18 15:08:58 +000097 /* Copy the saved copy of coreboot where coreboot runs */
98 /* Move ``longs'' the coreboot size is 4 byte aligned */
Eric Biederman8ca8d762003-04-22 19:02:15 +000099 " movl 16(%%esp), %%edi\n\t"
100 " movl 12(%%esp), %%esi\n\t"
101 " addl 8(%%esp), %%esi\n\t"
102 " movl 8(%%esp), %%ecx\n\t"
103 " shrl $2, %%ecx\n\t"
104 " rep movsl\n\t"
105
Stefan Reinauerf8ee1802008-01-18 15:08:58 +0000106 /* Adjust the stack pointer to point into the old coreboot image */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000107 " subl 20(%%esp), %%esp\n\t"
108
Stefan Reinauerf8ee1802008-01-18 15:08:58 +0000109 /* Adjust the instruction pointer to point into the old coreboot image */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000110 " movl $1f, %%eax\n\t"
111 " subl 20(%%esp), %%eax\n\t"
112 " jmp *%%eax\n\t"
113 "1: \n\t"
114
115 /* Drop the parameters I was passed */
116 " addl $24, %%esp\n\t"
117
118 /* Restore the callee save registers */
119 " popl %%ebx\n\t"
120 " popl %%edi\n\t"
121 " popl %%esi\n\t"
122
Stefan Reinauer14e22772010-04-27 06:56:47 +0000123 ::
Myles Watson2a63ea52009-03-20 18:29:49 +0000124 "ri" (lb_start), "ri" (buffer), "ri" (lb_size),
125 "ri" (entry),
Robert Millan81af3d42008-11-11 20:20:54 +0000126#if CONFIG_MULTIBOOT
Myles Watson2a63ea52009-03-20 18:29:49 +0000127 "ri"(mbi), "ri" (MB_MAGIC2)
Robert Millan81af3d42008-11-11 20:20:54 +0000128#else
Stefan Reinauere8b08ba2013-05-24 15:09:36 -0700129 "ri"(0), "ri" (0)
Robert Millan81af3d42008-11-11 20:20:54 +0000130#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000131 );
132}
Aaron Durbin8e4a3552013-02-08 17:28:04 -0600133#endif /* CONFIG_RELOCATABLE_RAMSTAGE */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000134
135