26#define ELF_DEVTREE_START ((void *)0x85FE0000)
27#define ELF_DEVTREE_MAX_SIZE 0x00010000
28#define MAX_CMDLINE_SIZE 255
30#define INITRD_RELOC_START ((void *)0x86000000)
31#define INITRD_MAX_SIZE (32 * 1024 * 1024)
36#define ELF_CODE_STACK_END ((void *)0x87F80000)
37#define ELF_CODE_RELOC_START ((void *)0x87F80000)
38#define ELF_CODE_MAX_SIZE 0x00080000
41#define ELF_TEMP_BEGIN ((void *)0x88000000)
42#define ELF_MAX_SIZE 0x05FE0000
45#define ELF_DATA_RELOC_START ((void *)0x8DFE0000)
46#define ELF_ARGV_BEGIN ((void *)0x93FC0000)
47#define ELF_GET_RELOCATED(x) \
48 (ELF_CODE_RELOC_START + ((unsigned long)(x) - (unsigned long)elfldr_start))
49#define ELF_GET_RELOCATED_REAL(x) (void*)((uint64_t)ELF_GET_RELOCATED(x) & 0x1FFFFFFF)
53#define elf_debug_printf printf
55#define elf_debug_printf(...)
63extern void elf_run(
unsigned long entry,
unsigned long devtree);
72static size_t initrd_size = 0;
74static char _filename[256] = {0};
75static char _filepath[256] = {0};
76static char _device[256] = {0};
78static inline __attribute__((always_inline))
void elf_putch(
unsigned char c) {
79 while (!((*(
volatile uint32_t *)(0xea001000 + 0x18)) & 0x02000000))
81 *(
volatile uint32_t *)(0xea001000 + 0x14) = (
c << 24) & 0xFF000000;
84static inline __attribute__((always_inline))
void elf_puts(
unsigned char *s) {
90elf_int2hex(
unsigned long long n,
unsigned char w,
unsigned char *
str) {
96 for (i = 0; i < w; ++i) {
97 d = (n >> (i << 2)) & 0x0f;
98 *--
str = (d <= 9) ? d + 48 : d + 55;
102static inline __attribute__((always_inline))
void elf_memset(
unsigned char *dst,
109elf_memcpy(
unsigned char *dst,
const unsigned char *src,
int l) {
116elf_sync(
volatile void *addr) {
117 asm volatile(
"dcbst 0, %0" : :
"b"(addr));
118 asm volatile(
"sync");
119 asm volatile(
"icbi 0, %0" : :
"b"(addr));
120 asm volatile(
"isync");
124elf_sync_before_exec(
unsigned char *dst,
int l) {
125 dst = (
unsigned char *)((
unsigned long)dst & (~(
LINESIZE - 1)));
138elf_smc_send_message(
const unsigned char *msg) {
139 while ((read32(0xEA001000 + 0x84) & 4) == 0)
142 write32(0xEA001000 + 0x84, 4);
143 write32n(0xEA001000 + 0x80, *(
uint32_t *)(msg + 0));
144 write32n(0xEA001000 + 0x80, *(
uint32_t *)(msg + 4));
145 write32n(0xEA001000 + 0x80, *(
uint32_t *)(msg + 8));
146 write32n(0xEA001000 + 0x80, *(
uint32_t *)(msg + 12));
147 write32(0xEA001000 + 0x84, 0);
150static inline __attribute__((always_inline))
void elf_smc_set_led(
int override,
153 elf_memset(buf, 0, 16);
159 elf_smc_send_message(buf);
168 __attribute__((section(
".elfldr"), used, noreturn, flatten, optimize(
"O2",
"no-tree-loop-distribute-patterns")))
169 elf_prepare_run_s2(
void *self,
uint32_t entry,
int mem_size) {
171 volatile void*
volatile zero = 0x0;
175 elf_sync_before_exec(zero, mem_size);
184 void *new_argv = (
void*)(0x00000008 + entry);
186 elf_sync_before_exec(new_argv,
sizeof(
struct __argv));
203 __attribute__((section(
".elfldr"), used, noreturn, flatten, optimize(
"O2",
"no-tree-loop-distribute-patterns")))
218 for (i = 0; i < ehdr->
e_phnum; ++i) {
220 elf_smc_set_led(1, (i << 4) & 0xF0);
246 elf_smc_set_led(1, 0x0F);
252 elf_smc_set_led(1, 0x87);
261 elf_prepare_run_s2(
NULL, 0, 0);
274 tmp = strrchr(argv,
'/');
279 strcpy(_filename, tmp + 1);
290 tmp = strrchr(argv,
'/');
295 strncpy(_filepath, argv, tmp - argv);
306 tmp = strrchr(argv,
':');
311 strncpy(_device, argv, tmp - argv);
321 memset(&args, 0,
sizeof(
struct __argv));
327 char *position = args.
argv + (
sizeof(
char *) *
argc);
330 for (i = 0; i <
argc; i++) {
331 strcpy(position,
argv[i]);
332 args.
argv[i] = position;
333 position += strlen(
argv[i]);
336 strcpy(position,
"\0");
345static int elf_VerifyHeaders(
void *addr,
int size) {
349 unsigned char *strtab = 0;
353 printf(
"ELF: Magic incorrect\n");
358 printf(
"ELF: Not a 32-bit file!\n Did you forget to convert it?\n");
367 strtab = (
unsigned char *)(addr + shdr->
sh_offset);
370 for (
int i = 0; i < ehdr->
e_phnum; i++) {
373 printf(
"ELF: Program header %d exceeds file size! (0x%.8X > 0x%.8X)\n",
387 for (
int i = 0; i < ehdr->
e_phnum; i++) {
395 return current_max_addr;
400 volatile uint32_t *elf_secondary_count_ptr =
404 if (elf_VerifyHeaders(addr,
size) != 0) {
405 printf(
" * Elf headers invalid, abort!\n", addr);
412 printf(
" * Elf is too large, abort! (size = 0x%.8X)\n", mapped_size);
417 printf(
" * Internal error: elfldr code is too large! (size = 0x%.8X)\n",
422 printf(
" * Executing @ 0x%.8X size 0x%.8X...\n", addr, mapped_size);
436 *elf_secondary_count_ptr = 0;
439 for (i = 1; i < 6; ++i) {
443 while (*elf_secondary_count_ptr < i) {
461 elf_prepare_run(
NULL, 0);
466 int f =
open(filename, O_RDONLY);
474 int size = s.st_size;
475 void *buf = malloc(
size);
501 printf(
" ! fdt_open_into() failed\n");
507 printf(
" ! /chosen node not found in devtree\n");
513 strlen(bootargs) + 1);
515 printf(
" ! couldn't set chosen.bootargs property\n");
520 if (initrd_start && initrd_size) {
528 printf(
" ! couldn't set chosen.linux,initrd-start property\n");
536 printf(
" ! couldn't set chosen.linux,initrd-end property\n");
541 printf(
" ! couldn't add reservation for the initrd\n");
548 printf(
" ! /memory node not found in devtree\n");
561 cpufreq = 3200000000;
565 cpufreq = 1300000000;
569 cpufreq = 1200000000;
573 printf(
" ! Weird CPU speed, assuming 3.2GHz\n");
574 cpufreq = 3200000000;
581 printf(
" ! /cpus/Xenon,PPE@0 node not found in devtree\n");
588 printf(
" ! couldn't set /cpus/Xenon,PPE@0.clock-frequency property\n");
594 printf(
" ! /cpus/Xenon,PPE@1 node not found in devtree\n");
601 printf(
" ! couldn't set /cpus/Xenon,PPE@1.clock-frequency property\n");
607 printf(
" ! /cpus/Xenon,PPE@2 node not found in devtree\n");
614 printf(
" ! couldn't set /cpus/Xenon,PPE@2.clock-frequency property\n");
620 printf(
" ! fdt_pack() failed\n");
625 printf(
" * Device tree prepared\n");
634 printf(
" ! Initrd bigger than INITRD_MAX_SIZE (32 MB), Aborting!\n");
638 if (initrd_start !=
NULL)
643 memcpy(initrd_start, start,
size);
649 printf(
" * Relocating initrd...\n");
658 printf(
" * Initrd at %p/0x%lx: %ld bytes (%ldKiB)\n", initrd_start,
659 (
u32)
PHYSADDR((
u32)initrd_start), initrd_size, initrd_size / 1024);
663 if (initrd_start !=
NULL)
682 printf(
" * Kernel command line: '%s'\n", bootargs);
void memicbi(void *addr, int len)
void memdcbst(void *addr, int len)
void kernel_reset_initrd(void)
void elf_run(unsigned long entry, unsigned long devtree)
#define ELF_GET_RELOCATED_REAL(x)
unsigned char elfldr_end[]
char * argv_GetFilepath(const char *argv)
#define ELF_GET_RELOCATED(x)
char * argv_GetFilename(const char *argv)
int kernel_prepare_initrd(void *start, size_t size)
int elf_runFromMemory(void *addr, int size)
void kernel_build_cmdline(const char *parameters, const char *root)
int elf_runFromDisk(char *filename)
void elf_call_real(uint64_t function,...)
#define elf_debug_printf(...)
#define ELF_CODE_MAX_SIZE
void elf_setArgcArgv(int argc, char *argv[])
volatile unsigned long elf_secondary_hold_addr
void kernel_relocate_initrd(void *start, size_t size)
volatile unsigned long elf_secondary_count
#define ELF_CODE_RELOC_START
unsigned char pagetable_end[]
#define ELF_DEVTREE_START
#define INITRD_RELOC_START
#define ELF_DEVTREE_MAX_SIZE
#define ELF_DATA_RELOC_START
char * argv_GetDevice(const char *argv)
int elf_runWithDeviceTree(void *elf_addr, int elf_size, void *dt_addr, int dt_size)
unsigned char elfldr_start[]
int fdt_path_offset(const void *fdt, const char *path)
int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
int fdt_open_into(const void *fdt, void *buf, int bufsize)
int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, int len)
unsigned int __mf_uintptr_t __attribute__((__mode__(__pointer__)))
int stat(const char *file, struct stat *st)
int read(int fileDesc, void *ptr, size_t len)
int open(const char *file, int flags, int mode)
unsigned char e_ident[EI_NIDENT]
int xenon_run_thread_task(int thread, void *stack, void *task)
void xenon_thread_startup(void)
uint64_t u64
64bit unsigned integer
uint32_t u32
32bit unsigned integer