blob: 08fabcfb4f7b727d78a4f8efd93e13a27d3be22d [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>
Aaron Durbin04654a22015-03-17 11:43:44 -05003#include <program_loading.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +00004#include <ip_checksum.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +00005#include <string.h>
6
Aaron Durbin8e4a3552013-02-08 17:28:04 -06007/* When the ramstage is relocatable the elf loading ensures an elf image cannot
8 * be loaded over the ramstage code. */
Aaron Durbin7d1996c2014-02-24 22:27:39 -06009static void jmp_payload_no_bounce_buffer(void *entry)
Aaron Durbin8e4a3552013-02-08 17:28:04 -060010{
Aaron Durbin8e4a3552013-02-08 17:28:04 -060011 /* Jump to kernel */
12 __asm__ __volatile__(
13 " cld \n\t"
14 /* Now jump to the loaded image */
15 " call *%0\n\t"
16
17 /* The loaded image returned? */
18 " cli \n\t"
19 " cld \n\t"
20
21 ::
Aaron Durbin7ae7fc02013-05-28 16:15:01 -050022 "r" (entry)
Aaron Durbin8e4a3552013-02-08 17:28:04 -060023 );
24}
Aaron Durbin7d1996c2014-02-24 22:27:39 -060025
26static void jmp_payload(void *entry, unsigned long buffer, unsigned long size)
Eric Biederman8ca8d762003-04-22 19:02:15 +000027{
28 extern unsigned char _ram_seg, _eram_seg;
29 unsigned long lb_start, lb_size;
Eric Biederman8ca8d762003-04-22 19:02:15 +000030
Eric Biederman8ca8d762003-04-22 19:02:15 +000031 lb_start = (unsigned long)&_ram_seg;
32 lb_size = (unsigned long)(&_eram_seg - &_ram_seg);
Eric Biederman8ca8d762003-04-22 19:02:15 +000033
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000034 printk(BIOS_SPEW, "entry = 0x%08lx\n", (unsigned long)entry);
35 printk(BIOS_SPEW, "lb_start = 0x%08lx\n", lb_start);
36 printk(BIOS_SPEW, "lb_size = 0x%08lx\n", lb_size);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000037 printk(BIOS_SPEW, "buffer = 0x%08lx\n", buffer);
Stefan Reinauer14e22772010-04-27 06:56:47 +000038
Eric Biederman8ca8d762003-04-22 19:02:15 +000039 /* Jump to kernel */
40 __asm__ __volatile__(
41 " cld \n\t"
42 /* Save the callee save registers... */
43 " pushl %%esi\n\t"
44 " pushl %%edi\n\t"
45 " pushl %%ebx\n\t"
46 /* Save the parameters I was passed */
47 " pushl $0\n\t" /* 20 adjust */
48 " pushl %0\n\t" /* 16 lb_start */
49 " pushl %1\n\t" /* 12 buffer */
50 " pushl %2\n\t" /* 8 lb_size */
51 " pushl %3\n\t" /* 4 entry */
52 " pushl %4\n\t" /* 0 elf_boot_notes */
53 /* Compute the adjustment */
54 " xorl %%eax, %%eax\n\t"
55 " subl 16(%%esp), %%eax\n\t"
56 " addl 12(%%esp), %%eax\n\t"
57 " addl 8(%%esp), %%eax\n\t"
58 " movl %%eax, 20(%%esp)\n\t"
Stefan Reinauerf834e202009-03-31 17:17:30 +000059 /* Place a copy of coreboot in its new location */
Stefan Reinauerf8ee1802008-01-18 15:08:58 +000060 /* Move ``longs'' the coreboot size is 4 byte aligned */
Eric Biederman8ca8d762003-04-22 19:02:15 +000061 " movl 12(%%esp), %%edi\n\t"
62 " addl 8(%%esp), %%edi\n\t"
63 " movl 16(%%esp), %%esi\n\t"
64 " movl 8(%%esp), %%ecx\n\n"
65 " shrl $2, %%ecx\n\t"
66 " rep movsl\n\t"
67
Stefan Reinauerf8ee1802008-01-18 15:08:58 +000068 /* Adjust the stack pointer to point into the new coreboot image */
Eric Biederman8ca8d762003-04-22 19:02:15 +000069 " addl 20(%%esp), %%esp\n\t"
Stefan Reinauerf8ee1802008-01-18 15:08:58 +000070 /* Adjust the instruction pointer to point into the new coreboot image */
Eric Biederman8ca8d762003-04-22 19:02:15 +000071 " movl $1f, %%eax\n\t"
72 " addl 20(%%esp), %%eax\n\t"
73 " jmp *%%eax\n\t"
74 "1: \n\t"
75
Stefan Reinauerf8ee1802008-01-18 15:08:58 +000076 /* Copy the coreboot bounce buffer over coreboot */
77 /* Move ``longs'' the coreboot size is 4 byte aligned */
Eric Biederman8ca8d762003-04-22 19:02:15 +000078 " movl 16(%%esp), %%edi\n\t"
79 " movl 12(%%esp), %%esi\n\t"
80 " movl 8(%%esp), %%ecx\n\t"
81 " shrl $2, %%ecx\n\t"
82 " rep movsl\n\t"
83
84 /* Now jump to the loaded image */
Robert Millan81af3d42008-11-11 20:20:54 +000085 " movl %5, %%eax\n\t"
Eric Biederman8ca8d762003-04-22 19:02:15 +000086 " movl 0(%%esp), %%ebx\n\t"
87 " call *4(%%esp)\n\t"
88
89 /* The loaded image returned? */
90 " cli \n\t"
91 " cld \n\t"
92
Stefan Reinauerf8ee1802008-01-18 15:08:58 +000093 /* Copy the saved copy of coreboot where coreboot runs */
94 /* Move ``longs'' the coreboot size is 4 byte aligned */
Eric Biederman8ca8d762003-04-22 19:02:15 +000095 " movl 16(%%esp), %%edi\n\t"
96 " movl 12(%%esp), %%esi\n\t"
97 " addl 8(%%esp), %%esi\n\t"
98 " movl 8(%%esp), %%ecx\n\t"
99 " shrl $2, %%ecx\n\t"
100 " rep movsl\n\t"
101
Stefan Reinauerf8ee1802008-01-18 15:08:58 +0000102 /* Adjust the stack pointer to point into the old coreboot image */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000103 " subl 20(%%esp), %%esp\n\t"
104
Stefan Reinauerf8ee1802008-01-18 15:08:58 +0000105 /* Adjust the instruction pointer to point into the old coreboot image */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000106 " movl $1f, %%eax\n\t"
107 " subl 20(%%esp), %%eax\n\t"
108 " jmp *%%eax\n\t"
109 "1: \n\t"
110
111 /* Drop the parameters I was passed */
112 " addl $24, %%esp\n\t"
113
114 /* Restore the callee save registers */
115 " popl %%ebx\n\t"
116 " popl %%edi\n\t"
117 " popl %%esi\n\t"
118
Stefan Reinauer14e22772010-04-27 06:56:47 +0000119 ::
Myles Watson2a63ea52009-03-20 18:29:49 +0000120 "ri" (lb_start), "ri" (buffer), "ri" (lb_size),
121 "ri" (entry),
Stefan Reinauere8b08ba2013-05-24 15:09:36 -0700122 "ri"(0), "ri" (0)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000123 );
124}
Eric Biederman8ca8d762003-04-22 19:02:15 +0000125
Aaron Durbince9efe02015-03-20 16:37:12 -0500126static void try_payload(struct prog *prog)
Aaron Durbin7d1996c2014-02-24 22:27:39 -0600127{
Aaron Durbince9efe02015-03-20 16:37:12 -0500128 if (prog->type == PROG_PAYLOAD) {
129 if (IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE))
130 jmp_payload_no_bounce_buffer(prog_entry(prog));
131 else
132 jmp_payload(prog_entry(prog),
133 (uintptr_t)prog_start(prog),
134 prog_size(prog));
135 }
Aaron Durbin7d1996c2014-02-24 22:27:39 -0600136}
Aaron Durbinb3847e62015-03-20 15:55:08 -0500137
138void arch_prog_run(struct prog *prog)
139{
Aaron Durbince9efe02015-03-20 16:37:12 -0500140 if (ENV_RAMSTAGE)
141 try_payload(prog);
Aaron Durbinb3847e62015-03-20 15:55:08 -0500142 __asm__ volatile (
143 "jmp *%%edi\n"
144 :: "D"(prog_entry(prog))
145 );
146}