1199767f8SToomas Soome /*-
2199767f8SToomas Soome  * Copyright (c) 2006 Marcel Moolenaar
3199767f8SToomas Soome  * All rights reserved.
4199767f8SToomas Soome  *
5199767f8SToomas Soome  * Redistribution and use in source and binary forms, with or without
6199767f8SToomas Soome  * modification, are permitted provided that the following conditions
7199767f8SToomas Soome  * are met:
8199767f8SToomas Soome  *
9199767f8SToomas Soome  * 1. Redistributions of source code must retain the above copyright
10199767f8SToomas Soome  *    notice, this list of conditions and the following disclaimer.
11199767f8SToomas Soome  * 2. Redistributions in binary form must reproduce the above copyright
12199767f8SToomas Soome  *    notice, this list of conditions and the following disclaimer in the
13199767f8SToomas Soome  *    documentation and/or other materials provided with the distribution.
14199767f8SToomas Soome  *
15199767f8SToomas Soome  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16199767f8SToomas Soome  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17199767f8SToomas Soome  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18199767f8SToomas Soome  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19199767f8SToomas Soome  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20199767f8SToomas Soome  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21199767f8SToomas Soome  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22199767f8SToomas Soome  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23199767f8SToomas Soome  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24199767f8SToomas Soome  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25199767f8SToomas Soome  */
26199767f8SToomas Soome 
27199767f8SToomas Soome #include <sys/cdefs.h>
28199767f8SToomas Soome 
29199767f8SToomas Soome #include <stand.h>
30199767f8SToomas Soome #include <string.h>
31199767f8SToomas Soome 
32199767f8SToomas Soome #include <sys/param.h>
33199767f8SToomas Soome #include <sys/linker.h>
34199767f8SToomas Soome #include <machine/elf.h>
35199767f8SToomas Soome 
36199767f8SToomas Soome #include <bootstrap.h>
37199767f8SToomas Soome 
38199767f8SToomas Soome #include <efi.h>
39199767f8SToomas Soome #include <efilib.h>
40199767f8SToomas Soome 
41199767f8SToomas Soome #include "loader_efi.h"
42199767f8SToomas Soome #include "cache.h"
43199767f8SToomas Soome 
44199767f8SToomas Soome #include "platform/acfreebsd.h"
45199767f8SToomas Soome #include "acconfig.h"
46199767f8SToomas Soome #define ACPI_SYSTEM_XFACE
47199767f8SToomas Soome #define ACPI_USE_SYSTEM_INTTYPES
48199767f8SToomas Soome #include "actypes.h"
49199767f8SToomas Soome #include "actbl.h"
50199767f8SToomas Soome 
51199767f8SToomas Soome static EFI_GUID acpi_guid = ACPI_TABLE_GUID;
52199767f8SToomas Soome static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
53199767f8SToomas Soome 
54199767f8SToomas Soome static int elf64_exec(struct preloaded_file *amp);
55199767f8SToomas Soome static int elf64_obj_exec(struct preloaded_file *amp);
56199767f8SToomas Soome 
57199767f8SToomas Soome int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp);
58199767f8SToomas Soome 
59199767f8SToomas Soome static struct file_format arm64_elf = {
60199767f8SToomas Soome 	elf64_loadfile,
61199767f8SToomas Soome 	elf64_exec
62199767f8SToomas Soome };
63199767f8SToomas Soome 
64199767f8SToomas Soome struct file_format *file_formats[] = {
65199767f8SToomas Soome 	&arm64_elf,
66199767f8SToomas Soome 	NULL
67199767f8SToomas Soome };
68199767f8SToomas Soome 
69199767f8SToomas Soome static int
elf64_exec(struct preloaded_file * fp)70199767f8SToomas Soome elf64_exec(struct preloaded_file *fp)
71199767f8SToomas Soome {
72199767f8SToomas Soome 	vm_offset_t modulep, kernendp;
73199767f8SToomas Soome 	vm_offset_t clean_addr;
74199767f8SToomas Soome 	size_t clean_size;
75199767f8SToomas Soome 	struct file_metadata *md;
76199767f8SToomas Soome 	ACPI_TABLE_RSDP *rsdp;
77199767f8SToomas Soome 	Elf_Ehdr *ehdr;
78199767f8SToomas Soome 	char buf[24];
79199767f8SToomas Soome 	int err, revision;
80199767f8SToomas Soome 	void (*entry)(vm_offset_t);
81199767f8SToomas Soome 
82199767f8SToomas Soome 	rsdp = efi_get_table(&acpi20_guid);
83199767f8SToomas Soome 	if (rsdp == NULL) {
84199767f8SToomas Soome 		rsdp = efi_get_table(&acpi_guid);
85199767f8SToomas Soome 	}
86199767f8SToomas Soome 	if (rsdp != NULL) {
87199767f8SToomas Soome 		sprintf(buf, "0x%016llx", (unsigned long long)rsdp);
88199767f8SToomas Soome 		setenv("hint.acpi.0.rsdp", buf, 1);
89199767f8SToomas Soome 		revision = rsdp->Revision;
90199767f8SToomas Soome 		if (revision == 0)
91199767f8SToomas Soome 			revision = 1;
92199767f8SToomas Soome 		sprintf(buf, "%d", revision);
93199767f8SToomas Soome 		setenv("hint.acpi.0.revision", buf, 1);
94199767f8SToomas Soome 		strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId));
95199767f8SToomas Soome 		buf[sizeof(rsdp->OemId)] = '\0';
96199767f8SToomas Soome 		setenv("hint.acpi.0.oem", buf, 1);
97199767f8SToomas Soome 		sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress);
98199767f8SToomas Soome 		setenv("hint.acpi.0.rsdt", buf, 1);
99199767f8SToomas Soome 		if (revision >= 2) {
100199767f8SToomas Soome 			/* XXX extended checksum? */
101199767f8SToomas Soome 			sprintf(buf, "0x%016llx",
102199767f8SToomas Soome 			    (unsigned long long)rsdp->XsdtPhysicalAddress);
103199767f8SToomas Soome 			setenv("hint.acpi.0.xsdt", buf, 1);
104199767f8SToomas Soome 			sprintf(buf, "%d", rsdp->Length);
105199767f8SToomas Soome 			setenv("hint.acpi.0.xsdt_length", buf, 1);
106199767f8SToomas Soome 		}
107199767f8SToomas Soome 	}
108199767f8SToomas Soome 
109199767f8SToomas Soome 	if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
11004f8e093SToomas Soome 		return (EFTYPE);
111199767f8SToomas Soome 
112199767f8SToomas Soome 	ehdr = (Elf_Ehdr *)&(md->md_data);
113199767f8SToomas Soome 	entry = efi_translate(ehdr->e_entry);
114199767f8SToomas Soome 
11504f8e093SToomas Soome 	efi_time_fini();
116199767f8SToomas Soome 	err = bi_load(fp->f_args, &modulep, &kernendp);
11704f8e093SToomas Soome 	if (err != 0) {
11804f8e093SToomas Soome 		efi_time_init();
119199767f8SToomas Soome 		return (err);
12004f8e093SToomas Soome 	}
121199767f8SToomas Soome 
122199767f8SToomas Soome 	dev_cleanup();
123199767f8SToomas Soome 
124199767f8SToomas Soome 	/* Clean D-cache under kernel area and invalidate whole I-cache */
125199767f8SToomas Soome 	clean_addr = (vm_offset_t)efi_translate(fp->f_addr);
126199767f8SToomas Soome 	clean_size = (vm_offset_t)efi_translate(kernendp) - clean_addr;
127199767f8SToomas Soome 
128199767f8SToomas Soome 	cpu_flush_dcache((void *)clean_addr, clean_size);
129199767f8SToomas Soome 	cpu_inval_icache(NULL, 0);
130199767f8SToomas Soome 
131199767f8SToomas Soome 	(*entry)(modulep);
132199767f8SToomas Soome 	panic("exec returned");
133199767f8SToomas Soome }
134199767f8SToomas Soome 
135199767f8SToomas Soome static int
elf64_obj_exec(struct preloaded_file * fp)136199767f8SToomas Soome elf64_obj_exec(struct preloaded_file *fp)
137199767f8SToomas Soome {
138199767f8SToomas Soome 
139199767f8SToomas Soome 	printf("%s called for preloaded file %p (=%s):\n", __func__, fp,
140199767f8SToomas Soome 	    fp->f_name);
141199767f8SToomas Soome 	return (ENOSYS);
142199767f8SToomas Soome }
143199767f8SToomas Soome 
144