elf_freebsd.c revision 283035
1203288Srnoland/*-
2203288Srnoland * Copyright (c) 2001 Benno Rice <benno@FreeBSD.org>
3203288Srnoland * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
4203288Srnoland * All rights reserved.
5203288Srnoland *
6203288Srnoland * Redistribution and use in source and binary forms, with or without
7203288Srnoland * modification, are permitted provided that the following conditions
8203288Srnoland * are met:
9203288Srnoland * 1. Redistributions of source code must retain the above copyright
10203288Srnoland *    notice, this list of conditions and the following disclaimer.
11203288Srnoland * 2. Redistributions in binary form must reproduce the above copyright
12203288Srnoland *    notice, this list of conditions and the following disclaimer in the
13203288Srnoland *    documentation and/or other materials provided with the distribution.
14203288Srnoland *
15203288Srnoland * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16203288Srnoland * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17203288Srnoland * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18203288Srnoland * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19203288Srnoland * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20203288Srnoland * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21203288Srnoland * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22203288Srnoland * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23203288Srnoland * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24203288Srnoland * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25203288Srnoland * SUCH DAMAGE.
26203288Srnoland */
27203288Srnoland
28203288Srnoland#include <sys/cdefs.h>
29203288Srnoland__FBSDID("$FreeBSD: head/sys/boot/uboot/lib/elf_freebsd.c 283035 2015-05-17 19:59:05Z ian $");
30203288Srnoland
31203288Srnoland#include <sys/param.h>
32203288Srnoland#include <sys/linker.h>
33203288Srnoland
34203288Srnoland#include <machine/md_var.h>
35203288Srnoland#include <machine/metadata.h>
36203288Srnoland#include <machine/elf.h>
37203288Srnoland
38203288Srnoland#include <stand.h>
39203288Srnoland
40203288Srnoland#include "bootstrap.h"
41203288Srnoland#include "libuboot.h"
42203288Srnoland
43203288Srnolandextern vm_offset_t md_load(char *, vm_offset_t *);
44203288Srnoland
45203288Srnolandint
46203288Srnoland__elfN(uboot_load)(char *filename, u_int64_t dest,
47203288Srnoland    struct preloaded_file **result)
48203288Srnoland{
49203288Srnoland	int r;
50203288Srnoland
51203288Srnoland	r = __elfN(loadfile)(filename, dest, result);
52203288Srnoland	if (r != 0)
53203288Srnoland		return (r);
54203288Srnoland
55203288Srnoland#if defined(__powerpc__)
56203288Srnoland	/*
57203288Srnoland	 * No need to sync the icache for modules: this will
58203288Srnoland	 * be done by the kernel after relocation.
59203288Srnoland	 */
60203288Srnoland	if (!strcmp((*result)->f_type, "elf kernel"))
61203288Srnoland		__syncicache((void *) (*result)->f_addr, (*result)->f_size);
62203288Srnoland#endif
63203288Srnoland	return (0);
64203288Srnoland}
65203288Srnoland
66203288Srnolandint
67203288Srnoland__elfN(uboot_exec)(struct preloaded_file *fp)
68203288Srnoland{
69203288Srnoland	struct file_metadata *fmp;
70203288Srnoland	vm_offset_t mdp;
71203288Srnoland	Elf_Ehdr *e;
72203288Srnoland	int error;
73203288Srnoland	void (*entry)(void *);
74203288Srnoland
75203288Srnoland	if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
76203288Srnoland		return (EFTYPE);
77203288Srnoland
78203288Srnoland	e = (Elf_Ehdr *)&fmp->md_data;
79203288Srnoland
80203288Srnoland	if ((error = md_load(fp->f_args, &mdp)) != 0)
81203288Srnoland		return (error);
82203288Srnoland
83203288Srnoland	entry = (void *)e->e_entry;
84203288Srnoland	printf("Kernel entry at 0x%x...\n", (unsigned)entry);
85203288Srnoland
86203288Srnoland	dev_cleanup();
87203288Srnoland	printf("Kernel args: %s\n", fp->f_args);
88203288Srnoland
89203288Srnoland	(*entry)((void *)mdp);
90203288Srnoland	panic("exec returned");
91203288Srnoland}
92203288Srnoland
93203288Srnolandstruct file_format uboot_elf = {
94203288Srnoland	__elfN(uboot_load),
95203288Srnoland	__elfN(uboot_exec)
96203288Srnoland};
97203288Srnoland