1176348Smarcel/*- 2176348Smarcel * Copyright (c) 2001 Benno Rice <benno@FreeBSD.org> 3176348Smarcel * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com> 4176348Smarcel * All rights reserved. 5176348Smarcel * 6176348Smarcel * Redistribution and use in source and binary forms, with or without 7176348Smarcel * modification, are permitted provided that the following conditions 8176348Smarcel * are met: 9176348Smarcel * 1. Redistributions of source code must retain the above copyright 10176348Smarcel * notice, this list of conditions and the following disclaimer. 11176348Smarcel * 2. Redistributions in binary form must reproduce the above copyright 12176348Smarcel * notice, this list of conditions and the following disclaimer in the 13176348Smarcel * documentation and/or other materials provided with the distribution. 14176348Smarcel * 15176348Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16176348Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17176348Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18176348Smarcel * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19176348Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20176348Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21176348Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22176348Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23176348Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24176348Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25176348Smarcel * SUCH DAMAGE. 26176348Smarcel */ 27176348Smarcel 28176348Smarcel#include <sys/cdefs.h> 29176348Smarcel__FBSDID("$FreeBSD$"); 30176348Smarcel 31176348Smarcel#include <sys/param.h> 32176348Smarcel#include <sys/linker.h> 33176348Smarcel 34182723Sraj#include <machine/md_var.h> 35176348Smarcel#include <machine/metadata.h> 36176348Smarcel#include <machine/elf.h> 37176348Smarcel 38176348Smarcel#include <stand.h> 39176348Smarcel 40176348Smarcel#include "bootstrap.h" 41235694Skientzle#include "libuboot.h" 42176348Smarcel 43182723Srajextern vm_offset_t md_load(char *, vm_offset_t *); 44182723Sraj 45176348Smarcelint 46176348Smarcel__elfN(uboot_load)(char *filename, u_int64_t dest, 47176348Smarcel struct preloaded_file **result) 48176348Smarcel{ 49182723Sraj int r; 50176348Smarcel 51176348Smarcel r = __elfN(loadfile)(filename, dest, result); 52176348Smarcel if (r != 0) 53176348Smarcel return (r); 54176348Smarcel 55176348Smarcel#if defined(__powerpc__) 56176348Smarcel /* 57176348Smarcel * No need to sync the icache for modules: this will 58176348Smarcel * be done by the kernel after relocation. 59176348Smarcel */ 60176348Smarcel if (!strcmp((*result)->f_type, "elf kernel")) 61176348Smarcel __syncicache((void *) (*result)->f_addr, (*result)->f_size); 62176348Smarcel#endif 63176348Smarcel return (0); 64176348Smarcel} 65176348Smarcel 66176348Smarcelint 67176348Smarcel__elfN(uboot_exec)(struct preloaded_file *fp) 68176348Smarcel{ 69182723Sraj struct file_metadata *fmp; 70182723Sraj vm_offset_t mdp; 71182723Sraj Elf_Ehdr *e; 72182723Sraj int error; 73235694Skientzle void (*entry)(void *); 74176348Smarcel 75182723Sraj if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) 76176348Smarcel return (EFTYPE); 77182723Sraj 78176348Smarcel e = (Elf_Ehdr *)&fmp->md_data; 79176348Smarcel 80176348Smarcel if ((error = md_load(fp->f_args, &mdp)) != 0) 81176348Smarcel return (error); 82176348Smarcel 83235694Skientzle entry = uboot_vm_translate(e->e_entry); 84235694Skientzle printf("Kernel entry at 0x%x...\n", (unsigned)entry); 85176348Smarcel 86176348Smarcel dev_cleanup(); 87247200Skientzle printf("Kernel args: %s\n", fp->f_args); 88176348Smarcel 89235694Skientzle (*entry)((void *)mdp); 90176348Smarcel panic("exec returned"); 91176348Smarcel} 92176348Smarcel 93177152Sobrienstruct file_format uboot_elf = { 94176348Smarcel __elfN(uboot_load), 95176348Smarcel __elfN(uboot_exec) 96176348Smarcel}; 97