1/*	$NetBSD: efi_stub.c,v 1.7 2022/08/21 10:30:54 riastradh Exp $	*/
2
3/*-
4 * Copyright (c) 2003,2004 Marcel Moolenaar
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30/* __FBSDID("$FreeBSD: src/sys/boot/ia64/libski/efi_stub.c,v 1.2 2003/09/08 09:11:32 obrien Exp $"); */
31
32
33#include <sys/types.h>
34#include <sys/stdint.h>
35
36#include <machine/bootinfo.h>
37#include <machine/efi.h>
38#include <lib/libsa/stand.h>
39#include <lib/libsa/loadfile.h>
40#include <bootstrap.h>
41
42#include "libski.h"
43
44extern char acpi_root[];
45extern char sal_systab[];
46
47extern void acpi_stub_init(void);
48extern void sal_stub_init(void);
49
50struct efi_cfgtbl efi_cfgtab[] = {
51	{ .ct_uuid = EFI_TABLE_ACPI20,	.ct_data = &acpi_root },
52	{ .ct_uuid = EFI_TABLE_SAL,	.ct_data = &sal_systab },
53};
54
55static efi_status GetTime(struct efi_tm *, struct efi_tmcap *);
56static efi_status SetTime(struct efi_tm *);
57static efi_status GetWakeupTime(uint8_t *, uint8_t *, struct efi_tm *);
58static efi_status SetWakeupTime(uint8_t, struct efi_tm *);
59
60static efi_status SetVirtualAddressMap(u_long, u_long, uint32_t,
61    struct efi_md*);
62static efi_status ConvertPointer(u_long, void **);
63
64static efi_status GetVariable(efi_char *, struct uuid *, uint32_t *, u_long *,
65    void *);
66static efi_status GetNextVariableName(u_long *, efi_char *, struct uuid *);
67static efi_status SetVariable(efi_char *, struct uuid *, uint32_t, u_long,
68    void *);
69
70static efi_status GetNextHighMonotonicCount(uint32_t *);
71static efi_status ResetSystem(enum efi_reset, efi_status, u_long, efi_char *);
72
73struct efi_rt efi_rttab = {
74	/* Header. */
75	.rt_hdr = {
76		.th_sig = 0,		/* XXX Signature */
77		.th_rev = 0,		/* XXX Revision */
78		.th_hdrsz = 0,		/* XXX HeaderSize */
79		.th_crc32 = 0,		/* XXX CRC32 */
80	},
81
82	/* Time services */
83	.rt_gettime = GetTime,
84	.rt_settime = SetTime,
85	.rt_getwaketime = GetWakeupTime,
86	.rt_setwaketime = SetWakeupTime,
87
88	/* Virtual memory services */
89	.rt_setvirtual = SetVirtualAddressMap,
90	.rt_cvtptr = ConvertPointer,
91
92	/* Variable services */
93	.rt_getvar = GetVariable,
94	.rt_scanvar = GetNextVariableName,
95	.rt_setvar = SetVariable,
96
97	/* Misc */
98	.rt_gethicnt = GetNextHighMonotonicCount,
99	.rt_reset = ResetSystem
100};
101
102struct efi_systbl efi_systab = {
103	/* Header. */
104	.st_hdr = {
105		.th_sig = EFI_SYSTBL_SIG,
106		.th_rev = 0,		/* XXX Revision */
107		.th_hdrsz = 0,		/* XXX HeaderSize */
108		.th_crc32 = 0,		/* XXX CRC32 */
109	},
110
111	/* Firmware info. */
112	.st_fwvendor = L"FreeBSD", .st_fwrev = 0, .__pad = 0,
113
114	/* Console stuff. */
115	.st_cin = NULL, .st_cinif = NULL,
116	.st_cout = NULL, .st_coutif = NULL,
117	.st_cerr = NULL, .st_cerrif = NULL,
118
119	/* Services (runtime first). */
120	.st_rt = &efi_rttab,
121	.st_bs = NULL,
122
123	/* Configuration tables. */
124	.st_entries = sizeof(efi_cfgtab)/sizeof(struct efi_cfgtbl),
125	.st_cfgtbl = efi_cfgtab,
126};
127
128static efi_status
129unsupported(const char *func)
130{
131	printf("EFI: %s not supported\n", func);
132	return ((1UL << 63) + 3);
133}
134
135static efi_status
136GetTime(struct efi_tm *time, struct efi_tmcap *caps)
137{
138	uint32_t comps[8];
139
140	ssc((uint64_t)comps, 0, 0, 0, SSC_GET_RTC);
141	time->tm_year = comps[0] + 1900;
142	time->tm_mon = comps[1] + 1;
143	time->tm_mday = comps[2];
144	time->tm_hour = comps[3];
145	time->tm_min = comps[4];
146	time->tm_sec = comps[5];
147	time->__pad1 = time->__pad2 = 0;
148	time->tm_nsec = 0;
149	time->tm_tz = 0;
150	time->tm_dst = 0;
151	return (0);
152}
153
154static efi_status
155SetTime(struct efi_tm *time)
156{
157	return (0);
158}
159
160static efi_status
161GetWakeupTime(uint8_t *enabled, uint8_t *pending, struct efi_tm *time)
162{
163	return (unsupported(__func__));
164}
165
166static efi_status
167SetWakeupTime(uint8_t enable, struct efi_tm *time)
168{
169	return (unsupported(__func__));
170}
171
172static void
173Reloc(void *addr, uint64_t delta)
174{
175	uint64_t **fpp = addr;
176
177	*fpp[0] += delta;
178	*fpp[1] += delta;
179	*fpp += delta >> 3;
180}
181
182static efi_status
183SetVirtualAddressMap(u_long mapsz, u_long descsz, uint32_t version,
184    struct efi_md *memmap)
185{
186	uint64_t delta;
187
188	delta = memmap->md_virt - memmap->md_phys;
189	Reloc(&efi_rttab.rt_gettime, delta);
190	Reloc(&efi_rttab.rt_settime, delta);
191	return (0);		/* Hah... */
192}
193
194static efi_status
195ConvertPointer(u_long debug, void **addr)
196{
197	return (unsupported(__func__));
198}
199
200static efi_status
201GetVariable(efi_char *name, struct uuid *vendor, uint32_t *attrs,
202    u_long *datasz, void *data)
203{
204	return (unsupported(__func__));
205}
206
207static efi_status
208GetNextVariableName(u_long *namesz, efi_char *name, struct uuid *vendor)
209{
210	return (unsupported(__func__));
211}
212
213static efi_status
214SetVariable(efi_char *name, struct uuid *vendor, uint32_t attrs, u_long datasz,
215    void *data)
216{
217	return (unsupported(__func__));
218}
219
220static efi_status
221GetNextHighMonotonicCount(uint32_t *high)
222{
223	static uint32_t counter = 0;
224
225	*high = counter++;
226	return (0);
227}
228
229static efi_status
230ResetSystem(enum efi_reset type, efi_status status, u_long datasz,
231    efi_char *data)
232{
233	return (unsupported(__func__));
234}
235
236int
237ski_init_stubs(struct bootinfo *bi)
238{
239	struct efi_md *memp;
240
241	/* Describe the SKI memory map. */
242	bi->bi_memmap = (u_int64_t)(bi + 1);
243	bi->bi_memmap_size = 4 * sizeof(struct efi_md);
244	bi->bi_memdesc_size = sizeof(struct efi_md);
245	bi->bi_memdesc_version = 1;
246
247	memp = (struct efi_md *)bi->bi_memmap;
248
249	memp[0].md_type = EFI_MD_TYPE_PALCODE;
250	memp[0].md_phys = 0x100000;
251	memp[0].md_virt = 0;
252	memp[0].md_pages = (4L*1024*1024)>>12;
253	memp[0].md_attr = EFI_MD_ATTR_WB | EFI_MD_ATTR_RT;
254
255	memp[1].md_type = EFI_MD_TYPE_FREE;
256	memp[1].md_phys = 5L*1024*1024;
257	memp[1].md_virt = 0;
258	memp[1].md_pages = (128L*1024*1024)>>12;
259	memp[1].md_attr = EFI_MD_ATTR_WB;
260
261	memp[2].md_type = EFI_MD_TYPE_FREE;
262	memp[2].md_phys = 4L*1024*1024*1024;
263	memp[2].md_virt = 0;
264	memp[2].md_pages = (64L*1024*1024)>>12;
265	memp[2].md_attr = EFI_MD_ATTR_WB;
266
267	memp[3].md_type = EFI_MD_TYPE_IOPORT;
268	memp[3].md_phys = 0xffffc000000;
269	memp[3].md_virt = 0;
270	memp[3].md_pages = (64L*1024*1024)>>12;
271	memp[3].md_attr = EFI_MD_ATTR_UC;
272
273	bi->bi_systab = (u_int64_t)&efi_systab;
274
275	sal_stub_init();
276	acpi_stub_init();
277
278	return (0);
279}
280