19dc70af8SWarner Losh /*-
29dc70af8SWarner Losh * Copyright (c) 2001 Benno Rice <benno@FreeBSD.org>
39dc70af8SWarner Losh * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
49dc70af8SWarner Losh * All rights reserved.
59dc70af8SWarner Losh *
69dc70af8SWarner Losh * Redistribution and use in source and binary forms, with or without
79dc70af8SWarner Losh * modification, are permitted provided that the following conditions
89dc70af8SWarner Losh * are met:
99dc70af8SWarner Losh * 1. Redistributions of source code must retain the above copyright
109dc70af8SWarner Losh * notice, this list of conditions and the following disclaimer.
119dc70af8SWarner Losh * 2. Redistributions in binary form must reproduce the above copyright
129dc70af8SWarner Losh * notice, this list of conditions and the following disclaimer in the
139dc70af8SWarner Losh * documentation and/or other materials provided with the distribution.
149dc70af8SWarner Losh *
159dc70af8SWarner Losh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
169dc70af8SWarner Losh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
179dc70af8SWarner Losh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
189dc70af8SWarner Losh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
199dc70af8SWarner Losh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
209dc70af8SWarner Losh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
219dc70af8SWarner Losh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
229dc70af8SWarner Losh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
239dc70af8SWarner Losh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
249dc70af8SWarner Losh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
259dc70af8SWarner Losh * SUCH DAMAGE.
269dc70af8SWarner Losh */
279dc70af8SWarner Losh
289dc70af8SWarner Losh #include <sys/param.h>
299dc70af8SWarner Losh #include <sys/linker.h>
309dc70af8SWarner Losh
319dc70af8SWarner Losh #include <machine/md_var.h>
329dc70af8SWarner Losh #include <machine/metadata.h>
339dc70af8SWarner Losh #include <machine/elf.h>
349dc70af8SWarner Losh
359dc70af8SWarner Losh #include <stand.h>
369dc70af8SWarner Losh
379dc70af8SWarner Losh #include "bootstrap.h"
389dc70af8SWarner Losh #include "libuboot.h"
39335615c4SWarner Losh #include "modinfo.h"
409dc70af8SWarner Losh
419dc70af8SWarner Losh int
__elfN(uboot_load)429dc70af8SWarner Losh __elfN(uboot_load)(char *filename, uint64_t dest,
439dc70af8SWarner Losh struct preloaded_file **result)
449dc70af8SWarner Losh {
459dc70af8SWarner Losh int r;
469dc70af8SWarner Losh
479dc70af8SWarner Losh r = __elfN(loadfile)(filename, dest, result);
489dc70af8SWarner Losh if (r != 0)
499dc70af8SWarner Losh return (r);
509dc70af8SWarner Losh
519dc70af8SWarner Losh #if defined(__powerpc__)
529dc70af8SWarner Losh /*
539dc70af8SWarner Losh * No need to sync the icache for modules: this will
549dc70af8SWarner Losh * be done by the kernel after relocation.
559dc70af8SWarner Losh */
56*86077f4fSAhmad Khalifa if (!strcmp((*result)->f_type, md_kerntype))
579dc70af8SWarner Losh __syncicache((void *) (*result)->f_addr, (*result)->f_size);
589dc70af8SWarner Losh #endif
599dc70af8SWarner Losh return (0);
609dc70af8SWarner Losh }
619dc70af8SWarner Losh
629dc70af8SWarner Losh int
__elfN(uboot_exec)639dc70af8SWarner Losh __elfN(uboot_exec)(struct preloaded_file *fp)
649dc70af8SWarner Losh {
659dc70af8SWarner Losh struct file_metadata *fmp;
669dc70af8SWarner Losh vm_offset_t mdp;
679dc70af8SWarner Losh Elf_Ehdr *e;
689dc70af8SWarner Losh int error;
699dc70af8SWarner Losh void (*entry)(void *);
709dc70af8SWarner Losh
719dc70af8SWarner Losh if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
729dc70af8SWarner Losh return (EFTYPE);
739dc70af8SWarner Losh
749dc70af8SWarner Losh e = (Elf_Ehdr *)&fmp->md_data;
759dc70af8SWarner Losh
769dc70af8SWarner Losh if ((error = md_load(fp->f_args, &mdp, NULL)) != 0)
779dc70af8SWarner Losh return (error);
789dc70af8SWarner Losh
799dc70af8SWarner Losh entry = (void *)e->e_entry;
809dc70af8SWarner Losh printf("Kernel entry at %p...\n", entry);
819dc70af8SWarner Losh
829dc70af8SWarner Losh dev_cleanup();
839dc70af8SWarner Losh printf("Kernel args: %s\n", fp->f_args);
849dc70af8SWarner Losh
859dc70af8SWarner Losh (*entry)((void *)mdp);
869dc70af8SWarner Losh panic("exec returned");
879dc70af8SWarner Losh }
889dc70af8SWarner Losh
899dc70af8SWarner Losh struct file_format uboot_elf = {
909dc70af8SWarner Losh __elfN(uboot_load),
919dc70af8SWarner Losh __elfN(uboot_exec)
929dc70af8SWarner Losh };
93