1217044Snwhitehorn/*-
2217044Snwhitehorn * Copyright (c) 2001 Benno Rice <benno@FreeBSD.org>
3217044Snwhitehorn * All rights reserved.
4217044Snwhitehorn *
5217044Snwhitehorn * Redistribution and use in source and binary forms, with or without
6217044Snwhitehorn * modification, are permitted provided that the following conditions
7217044Snwhitehorn * are met:
8217044Snwhitehorn * 1. Redistributions of source code must retain the above copyright
9217044Snwhitehorn *    notice, this list of conditions and the following disclaimer.
10217044Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright
11217044Snwhitehorn *    notice, this list of conditions and the following disclaimer in the
12217044Snwhitehorn *    documentation and/or other materials provided with the distribution.
13217044Snwhitehorn *
14217044Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15217044Snwhitehorn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16217044Snwhitehorn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17217044Snwhitehorn * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18217044Snwhitehorn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19217044Snwhitehorn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20217044Snwhitehorn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21217044Snwhitehorn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22217044Snwhitehorn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23217044Snwhitehorn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24217044Snwhitehorn * SUCH DAMAGE.
25217044Snwhitehorn */
26217044Snwhitehorn
27217044Snwhitehorn#include <sys/cdefs.h>
28217044Snwhitehorn__FBSDID("$FreeBSD$");
29217044Snwhitehorn
30217044Snwhitehorn#define __ELF_WORD_SIZE 64
31217044Snwhitehorn
32217044Snwhitehorn#include <sys/param.h>
33217044Snwhitehorn#include <sys/linker.h>
34217044Snwhitehorn
35217044Snwhitehorn#include <machine/metadata.h>
36217044Snwhitehorn#include <machine/elf.h>
37217044Snwhitehorn
38217044Snwhitehorn#include <stand.h>
39217044Snwhitehorn
40217044Snwhitehorn#include "bootstrap.h"
41217044Snwhitehorn
42217044Snwhitehornextern char		end[];
43217044Snwhitehornextern vm_offset_t	reloc;	/* From <arch>/conf.c */
44217044Snwhitehorn
45217044Snwhitehornint
46217044Snwhitehornppc64_elf_loadfile(char *filename, u_int64_t dest,
47217044Snwhitehorn    struct preloaded_file **result)
48217044Snwhitehorn{
49217044Snwhitehorn	int	r;
50217044Snwhitehorn
51217044Snwhitehorn	r = __elfN(loadfile)(filename, dest, result);
52217044Snwhitehorn	if (r != 0)
53217044Snwhitehorn		return (r);
54217044Snwhitehorn
55217044Snwhitehorn	/*
56217044Snwhitehorn	 * No need to sync the icache for modules: this will
57217044Snwhitehorn	 * be done by the kernel after relocation.
58217044Snwhitehorn	 */
59217044Snwhitehorn	if (!strcmp((*result)->f_type, "elf kernel"))
60217044Snwhitehorn		__syncicache((void *) (*result)->f_addr, (*result)->f_size);
61217044Snwhitehorn	return (0);
62217044Snwhitehorn}
63217044Snwhitehorn
64217044Snwhitehornint
65217044Snwhitehornppc64_elf_exec(struct preloaded_file *fp)
66217044Snwhitehorn{
67217044Snwhitehorn	struct file_metadata	*fmp;
68217044Snwhitehorn	vm_offset_t		mdp;
69217044Snwhitehorn	Elf_Ehdr		*e;
70217044Snwhitehorn	int			error;
71217044Snwhitehorn	int (*entry)(u_long, u_long, u_long, void *, u_long);
72217044Snwhitehorn
73217044Snwhitehorn	if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) {
74217044Snwhitehorn		return(EFTYPE);
75217044Snwhitehorn	}
76217044Snwhitehorn	e = (Elf_Ehdr *)&fmp->md_data;
77217044Snwhitehorn
78217044Snwhitehorn	/* Handle function descriptor */
79217044Snwhitehorn	entry = (void *)(uintptr_t)(*(uint64_t *)e->e_entry);
80217044Snwhitehorn
81217044Snwhitehorn	if ((error = md_load64(fp->f_args, &mdp)) != 0)
82217044Snwhitehorn		return (error);
83217044Snwhitehorn
84217044Snwhitehorn	printf("Kernel entry at %p ...\n", entry);
85217044Snwhitehorn
86217044Snwhitehorn	dev_cleanup();
87217044Snwhitehorn
88217044Snwhitehorn	entry(0 /* FDT */, 0 /* Phys. mem offset */, 0 /* OF entry */,
89217044Snwhitehorn	     (void *)mdp, sizeof(mdp));
90217044Snwhitehorn
91217044Snwhitehorn	panic("exec returned");
92217044Snwhitehorn}
93217044Snwhitehorn
94217044Snwhitehornstruct file_format	ppc_elf64 =
95217044Snwhitehorn{
96217044Snwhitehorn	ppc64_elf_loadfile,
97217044Snwhitehorn	ppc64_elf_exec
98217044Snwhitehorn};
99