1139738Simp/*-
2135699Smarcel * Copyright (c) 2003,2004 Marcel Moolenaar
3110211Smarcel * All rights reserved.
4110211Smarcel *
5110211Smarcel * Redistribution and use in source and binary forms, with or without
6110211Smarcel * modification, are permitted provided that the following conditions
7110211Smarcel * are met:
8110211Smarcel *
9110211Smarcel * 1. Redistributions of source code must retain the above copyright
10110211Smarcel *    notice, this list of conditions and the following disclaimer.
11110211Smarcel * 2. Redistributions in binary form must reproduce the above copyright
12110211Smarcel *    notice, this list of conditions and the following disclaimer in the
13110211Smarcel *    documentation and/or other materials provided with the distribution.
14110211Smarcel *
15110211Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16110211Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17110211Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18110211Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19110211Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20110211Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21110211Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22110211Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23110211Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24110211Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25110211Smarcel */
26110211Smarcel
27119880Sobrien#include <sys/cdefs.h>
28119880Sobrien__FBSDID("$FreeBSD$");
29119880Sobrien
30110211Smarcel#include <sys/types.h>
31220313Smarcel#include <machine/bootinfo.h>
32135699Smarcel#include <machine/efi.h>
33110211Smarcel#include <stand.h>
34110211Smarcel#include "libski.h"
35110211Smarcel
36110211Smarcelextern void acpi_root;
37110211Smarcelextern void sal_systab;
38110211Smarcel
39135699Smarcelstruct efi_cfgtbl efi_cfgtab[] = {
40135699Smarcel	{ EFI_TABLE_ACPI20,	(intptr_t)&acpi_root },
41135699Smarcel	{ EFI_TABLE_SAL,	(intptr_t)&sal_systab }
42110211Smarcel};
43110211Smarcel
44135699Smarcelstatic efi_status GetTime(struct efi_tm *, struct efi_tmcap *);
45135699Smarcelstatic efi_status SetTime(struct efi_tm *);
46135699Smarcelstatic efi_status GetWakeupTime(uint8_t *, uint8_t *, struct efi_tm *);
47135699Smarcelstatic efi_status SetWakeupTime(uint8_t, struct efi_tm *);
48110211Smarcel
49135699Smarcelstatic efi_status SetVirtualAddressMap(u_long, u_long, uint32_t,
50135699Smarcel    struct efi_md*);
51135699Smarcelstatic efi_status ConvertPointer(u_long, void **);
52110211Smarcel
53135699Smarcelstatic efi_status GetVariable(efi_char *, struct uuid *, uint32_t *, u_long *,
54135699Smarcel    void *);
55135699Smarcelstatic efi_status GetNextVariableName(u_long *, efi_char *, struct uuid *);
56135699Smarcelstatic efi_status SetVariable(efi_char *, struct uuid *, uint32_t, u_long,
57135699Smarcel    void *);
58110211Smarcel
59135699Smarcelstatic efi_status GetNextHighMonotonicCount(uint32_t *);
60135699Smarcelstatic efi_status ResetSystem(enum efi_reset, efi_status, u_long, efi_char *);
61110211Smarcel
62135699Smarcelstruct efi_rt efi_rttab = {
63110211Smarcel	/* Header. */
64135699Smarcel	{	0,			/* XXX Signature */
65135699Smarcel		0,			/* XXX Revision */
66110211Smarcel		0,			/* XXX HeaderSize */
67110211Smarcel		0,			/* XXX CRC32 */
68110211Smarcel	},
69110211Smarcel
70110211Smarcel	/* Time services */
71110211Smarcel	GetTime,
72110211Smarcel	SetTime,
73110211Smarcel	GetWakeupTime,
74110211Smarcel	SetWakeupTime,
75110211Smarcel
76110211Smarcel	/* Virtual memory services */
77110211Smarcel	SetVirtualAddressMap,
78110211Smarcel	ConvertPointer,
79110211Smarcel
80110211Smarcel	/* Variable services */
81110211Smarcel	GetVariable,
82110211Smarcel	GetNextVariableName,
83110211Smarcel	SetVariable,
84110211Smarcel
85110211Smarcel	/* Misc */
86110211Smarcel	GetNextHighMonotonicCount,
87110211Smarcel	ResetSystem
88110211Smarcel};
89110211Smarcel
90135699Smarcelstruct efi_systbl efi_systab = {
91110211Smarcel	/* Header. */
92135699Smarcel	{	EFI_SYSTBL_SIG,
93135699Smarcel		0,			/* XXX Revision */
94135699Smarcel		0,			/* XXX HeaderSize */
95135699Smarcel		0,			/* XXX CRC32 */
96110211Smarcel	},
97110211Smarcel
98110211Smarcel	/* Firmware info. */
99135699Smarcel	L"FreeBSD", 0, 0,
100110211Smarcel
101110211Smarcel	/* Console stuff. */
102110211Smarcel	NULL, NULL,
103110211Smarcel	NULL, NULL,
104110211Smarcel	NULL, NULL,
105110211Smarcel
106110211Smarcel	/* Services (runtime first). */
107135699Smarcel	(intptr_t)&efi_rttab,
108110211Smarcel	NULL,
109110211Smarcel
110110211Smarcel	/* Configuration tables. */
111135699Smarcel	sizeof(efi_cfgtab)/sizeof(struct efi_cfgtbl),
112135699Smarcel	(intptr_t)efi_cfgtab
113110211Smarcel};
114110211Smarcel
115135699Smarcelstatic efi_status
116110211Smarcelunsupported(const char *func)
117110211Smarcel{
118110211Smarcel	printf("EFI: %s not supported\n", func);
119135699Smarcel	return ((1UL << 63) + 3);
120110211Smarcel}
121110211Smarcel
122135699Smarcelstatic efi_status
123135699SmarcelGetTime(struct efi_tm *time, struct efi_tmcap *caps)
124110211Smarcel{
125135699Smarcel	uint32_t comps[8];
126110211Smarcel
127135699Smarcel	ssc((uint64_t)comps, 0, 0, 0, SSC_GET_RTC);
128135699Smarcel	time->tm_year = comps[0] + 1900;
129135699Smarcel	time->tm_mon = comps[1] + 1;
130135699Smarcel	time->tm_mday = comps[2];
131135699Smarcel	time->tm_hour = comps[3];
132135699Smarcel	time->tm_min = comps[4];
133135699Smarcel	time->tm_sec = comps[5];
134135699Smarcel	time->__pad1 = time->__pad2 = 0;
135135699Smarcel	time->tm_nsec = 0;
136135699Smarcel	time->tm_tz = 0;
137135699Smarcel	time->tm_dst = 0;
138135699Smarcel	return (0);
139110211Smarcel}
140110211Smarcel
141135699Smarcelstatic efi_status
142135699SmarcelSetTime(struct efi_tm *time)
143110211Smarcel{
144135699Smarcel	return (0);
145110211Smarcel}
146110211Smarcel
147135699Smarcelstatic efi_status
148135699SmarcelGetWakeupTime(uint8_t *enabled, uint8_t *pending, struct efi_tm *time)
149110211Smarcel{
150110211Smarcel	return (unsupported(__func__));
151110211Smarcel}
152110211Smarcel
153135699Smarcelstatic efi_status
154135699SmarcelSetWakeupTime(uint8_t enable, struct efi_tm *time)
155110211Smarcel{
156110211Smarcel	return (unsupported(__func__));
157110211Smarcel}
158110211Smarcel
159110211Smarcelstatic void
160135699SmarcelReloc(void *addr, uint64_t delta)
161110211Smarcel{
162135699Smarcel	uint64_t **fpp = addr;
163110211Smarcel
164110211Smarcel	*fpp[0] += delta;
165110211Smarcel	*fpp[1] += delta;
166110211Smarcel	*fpp += delta >> 3;
167110211Smarcel}
168110211Smarcel
169135699Smarcelstatic efi_status
170135699SmarcelSetVirtualAddressMap(u_long mapsz, u_long descsz, uint32_t version,
171135699Smarcel    struct efi_md *memmap)
172110211Smarcel{
173135699Smarcel	uint64_t delta;
174110211Smarcel
175135699Smarcel	delta = (uintptr_t)memmap->md_virt - memmap->md_phys;
176135699Smarcel	Reloc(&efi_rttab.rt_gettime, delta);
177135699Smarcel	Reloc(&efi_rttab.rt_settime, delta);
178135699Smarcel	return (0);		/* Hah... */
179110211Smarcel}
180110211Smarcel
181135699Smarcelstatic efi_status
182135699SmarcelConvertPointer(u_long debug, void **addr)
183110211Smarcel{
184110211Smarcel	return (unsupported(__func__));
185110211Smarcel}
186110211Smarcel
187135699Smarcelstatic efi_status
188135699SmarcelGetVariable(efi_char *name, struct uuid *vendor, uint32_t *attrs,
189135699Smarcel    u_long *datasz, void *data)
190110211Smarcel{
191110211Smarcel	return (unsupported(__func__));
192110211Smarcel}
193110211Smarcel
194135699Smarcelstatic efi_status
195135699SmarcelGetNextVariableName(u_long *namesz, efi_char *name, struct uuid *vendor)
196110211Smarcel{
197110211Smarcel	return (unsupported(__func__));
198110211Smarcel}
199110211Smarcel
200135699Smarcelstatic efi_status
201135699SmarcelSetVariable(efi_char *name, struct uuid *vendor, uint32_t attrs, u_long datasz,
202135699Smarcel    void *data)
203110211Smarcel{
204110211Smarcel	return (unsupported(__func__));
205110211Smarcel}
206110211Smarcel
207135699Smarcelstatic efi_status
208135699SmarcelGetNextHighMonotonicCount(uint32_t *high)
209110211Smarcel{
210135699Smarcel	static uint32_t counter = 0;
211110211Smarcel
212110211Smarcel	*high = counter++;
213135699Smarcel	return (0);
214110211Smarcel}
215110211Smarcel
216135699Smarcelstatic efi_status
217135699SmarcelResetSystem(enum efi_reset type, efi_status status, u_long datasz,
218135699Smarcel    efi_char *data)
219110211Smarcel{
220110211Smarcel	return (unsupported(__func__));
221110211Smarcel}
222110211Smarcel
223164010Smarcelvoid
224164010Smarcelefi_stub_init(struct bootinfo *bi)
225110211Smarcel{
226220283Smarcel	static struct efi_md memmap[4];
227110211Smarcel
228110211Smarcel	/* Describe the SKI memory map. */
229220283Smarcel	bi->bi_memmap = (uintptr_t)(void *)memmap;
230220283Smarcel	bi->bi_memmap_size = sizeof(memmap);
231135699Smarcel	bi->bi_memdesc_size = sizeof(struct efi_md);
232110211Smarcel	bi->bi_memdesc_version = 1;
233110211Smarcel
234220283Smarcel	memmap[0].md_type = EFI_MD_TYPE_PALCODE;
235220283Smarcel	memmap[0].md_phys = 0x100000;
236220283Smarcel	memmap[0].md_virt = NULL;
237220283Smarcel	memmap[0].md_pages = (1L*1024*1024)>>12;
238220283Smarcel	memmap[0].md_attr = EFI_MD_ATTR_WB | EFI_MD_ATTR_RT;
239110211Smarcel
240220283Smarcel	memmap[1].md_type = EFI_MD_TYPE_FREE;
241220283Smarcel	memmap[1].md_phys = 4L*1024*1024;
242220283Smarcel	memmap[1].md_virt = NULL;
243220283Smarcel	memmap[1].md_pages = (128L*1024*1024)>>12;
244220283Smarcel	memmap[1].md_attr = EFI_MD_ATTR_WB;
245110211Smarcel
246220283Smarcel	memmap[2].md_type = EFI_MD_TYPE_FREE;
247220283Smarcel	memmap[2].md_phys = 4L*1024*1024*1024;
248220283Smarcel	memmap[2].md_virt = NULL;
249220283Smarcel	memmap[2].md_pages = (64L*1024*1024)>>12;
250220283Smarcel	memmap[2].md_attr = EFI_MD_ATTR_WB;
251110211Smarcel
252220283Smarcel	memmap[3].md_type = EFI_MD_TYPE_IOPORT;
253220283Smarcel	memmap[3].md_phys = 0xffffc000000;
254220283Smarcel	memmap[3].md_virt = NULL;
255220283Smarcel	memmap[3].md_pages = (64L*1024*1024)>>12;
256220283Smarcel	memmap[3].md_attr = EFI_MD_ATTR_UC;
257110211Smarcel
258110211Smarcel	bi->bi_systab = (u_int64_t)&efi_systab;
259110211Smarcel}
260