efi_stub.c revision 135699
1248590Smm/*
2248590Smm * Copyright (c) 2003,2004 Marcel Moolenaar
3248590Smm * All rights reserved.
4248590Smm *
5248590Smm * Redistribution and use in source and binary forms, with or without
6248590Smm * modification, are permitted provided that the following conditions
7248590Smm * are met:
8248590Smm *
9248590Smm * 1. Redistributions of source code must retain the above copyright
10248590Smm *    notice, this list of conditions and the following disclaimer.
11248590Smm * 2. Redistributions in binary form must reproduce the above copyright
12248590Smm *    notice, this list of conditions and the following disclaimer in the
13248590Smm *    documentation and/or other materials provided with the distribution.
14248590Smm *
15248590Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16248590Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17248590Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18248590Smm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19248590Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20248590Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21248590Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22248590Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23248590Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24248590Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25248590Smm */
26248590Smm
27248590Smm#include <sys/cdefs.h>
28248590Smm__FBSDID("$FreeBSD: head/sys/boot/ia64/ski/efi_stub.c 135699 2004-09-24 04:35:07Z marcel $");
29248590Smm
30248590Smm#include <sys/types.h>
31248590Smm#include <machine/bootinfo.h>
32248590Smm#include <machine/efi.h>
33248590Smm#include <stand.h>
34248590Smm#include "libski.h"
35248590Smm
36248590Smmextern void acpi_root;
37248590Smmextern void sal_systab;
38248590Smm
39248590Smmextern void acpi_stub_init(void);
40248590Smmextern void sal_stub_init(void);
41248590Smm
42248590Smmstruct efi_cfgtbl efi_cfgtab[] = {
43248590Smm	{ EFI_TABLE_ACPI20,	(intptr_t)&acpi_root },
44248590Smm	{ EFI_TABLE_SAL,	(intptr_t)&sal_systab }
45248590Smm};
46248590Smm
47248590Smmstatic efi_status GetTime(struct efi_tm *, struct efi_tmcap *);
48248590Smmstatic efi_status SetTime(struct efi_tm *);
49248590Smmstatic efi_status GetWakeupTime(uint8_t *, uint8_t *, struct efi_tm *);
50248590Smmstatic efi_status SetWakeupTime(uint8_t, struct efi_tm *);
51248590Smm
52248590Smmstatic efi_status SetVirtualAddressMap(u_long, u_long, uint32_t,
53248590Smm    struct efi_md*);
54248590Smmstatic efi_status ConvertPointer(u_long, void **);
55248590Smm
56248590Smmstatic efi_status GetVariable(efi_char *, struct uuid *, uint32_t *, u_long *,
57248590Smm    void *);
58248590Smmstatic efi_status GetNextVariableName(u_long *, efi_char *, struct uuid *);
59248590Smmstatic efi_status SetVariable(efi_char *, struct uuid *, uint32_t, u_long,
60248590Smm    void *);
61248590Smm
62248590Smmstatic efi_status GetNextHighMonotonicCount(uint32_t *);
63248590Smmstatic efi_status ResetSystem(enum efi_reset, efi_status, u_long, efi_char *);
64248590Smm
65248590Smmstruct efi_rt efi_rttab = {
66248590Smm	/* Header. */
67248590Smm	{	0,			/* XXX Signature */
68248590Smm		0,			/* XXX Revision */
69248590Smm		0,			/* XXX HeaderSize */
70248590Smm		0,			/* XXX CRC32 */
71248590Smm	},
72248590Smm
73248590Smm	/* Time services */
74248590Smm	GetTime,
75248590Smm	SetTime,
76248590Smm	GetWakeupTime,
77248590Smm	SetWakeupTime,
78248590Smm
79248590Smm	/* Virtual memory services */
80248590Smm	SetVirtualAddressMap,
81248590Smm	ConvertPointer,
82248590Smm
83248590Smm	/* Variable services */
84248590Smm	GetVariable,
85248590Smm	GetNextVariableName,
86248590Smm	SetVariable,
87248590Smm
88248590Smm	/* Misc */
89248590Smm	GetNextHighMonotonicCount,
90248590Smm	ResetSystem
91248590Smm};
92248590Smm
93248590Smmstruct efi_systbl efi_systab = {
94248590Smm	/* Header. */
95248590Smm	{	EFI_SYSTBL_SIG,
96248590Smm		0,			/* XXX Revision */
97248590Smm		0,			/* XXX HeaderSize */
98248590Smm		0,			/* XXX CRC32 */
99248590Smm	},
100248590Smm
101248590Smm	/* Firmware info. */
102248590Smm	L"FreeBSD", 0, 0,
103248590Smm
104248590Smm	/* Console stuff. */
105248590Smm	NULL, NULL,
106248590Smm	NULL, NULL,
107248590Smm	NULL, NULL,
108248590Smm
109248590Smm	/* Services (runtime first). */
110248590Smm	(intptr_t)&efi_rttab,
111248590Smm	NULL,
112248590Smm
113248590Smm	/* Configuration tables. */
114248590Smm	sizeof(efi_cfgtab)/sizeof(struct efi_cfgtbl),
115248590Smm	(intptr_t)efi_cfgtab
116248590Smm};
117248590Smm
118248590Smmstatic efi_status
119248590Smmunsupported(const char *func)
120248590Smm{
121248590Smm	printf("EFI: %s not supported\n", func);
122248590Smm	return ((1UL << 63) + 3);
123248590Smm}
124248590Smm
125248590Smmstatic efi_status
126248590SmmGetTime(struct efi_tm *time, struct efi_tmcap *caps)
127248590Smm{
128248590Smm	uint32_t comps[8];
129248590Smm
130248590Smm	ssc((uint64_t)comps, 0, 0, 0, SSC_GET_RTC);
131248590Smm	time->tm_year = comps[0] + 1900;
132248590Smm	time->tm_mon = comps[1] + 1;
133248590Smm	time->tm_mday = comps[2];
134248590Smm	time->tm_hour = comps[3];
135248590Smm	time->tm_min = comps[4];
136248590Smm	time->tm_sec = comps[5];
137248590Smm	time->__pad1 = time->__pad2 = 0;
138248590Smm	time->tm_nsec = 0;
139248590Smm	time->tm_tz = 0;
140248590Smm	time->tm_dst = 0;
141248590Smm	return (0);
142248590Smm}
143248590Smm
144248590Smmstatic efi_status
145248590SmmSetTime(struct efi_tm *time)
146248590Smm{
147248590Smm	return (0);
148248590Smm}
149248590Smm
150248590Smmstatic efi_status
151248590SmmGetWakeupTime(uint8_t *enabled, uint8_t *pending, struct efi_tm *time)
152248590Smm{
153248590Smm	return (unsupported(__func__));
154248590Smm}
155248590Smm
156248590Smmstatic efi_status
157248590SmmSetWakeupTime(uint8_t enable, struct efi_tm *time)
158248590Smm{
159248590Smm	return (unsupported(__func__));
160248590Smm}
161248590Smm
162248590Smmstatic void
163248590SmmReloc(void *addr, uint64_t delta)
164248590Smm{
165248590Smm	uint64_t **fpp = addr;
166248590Smm
167248590Smm	*fpp[0] += delta;
168248590Smm	*fpp[1] += delta;
169248590Smm	*fpp += delta >> 3;
170248590Smm}
171248590Smm
172248590Smmstatic efi_status
173248590SmmSetVirtualAddressMap(u_long mapsz, u_long descsz, uint32_t version,
174248590Smm    struct efi_md *memmap)
175248590Smm{
176248590Smm	uint64_t delta;
177248590Smm
178248590Smm	delta = (uintptr_t)memmap->md_virt - memmap->md_phys;
179248590Smm	Reloc(&efi_rttab.rt_gettime, delta);
180248590Smm	Reloc(&efi_rttab.rt_settime, delta);
181248590Smm	return (0);		/* Hah... */
182248590Smm}
183248590Smm
184248590Smmstatic efi_status
185248590SmmConvertPointer(u_long debug, void **addr)
186248590Smm{
187248590Smm	return (unsupported(__func__));
188248590Smm}
189248590Smm
190248590Smmstatic efi_status
191248590SmmGetVariable(efi_char *name, struct uuid *vendor, uint32_t *attrs,
192248590Smm    u_long *datasz, void *data)
193248590Smm{
194248590Smm	return (unsupported(__func__));
195248590Smm}
196248590Smm
197248590Smmstatic efi_status
198248590SmmGetNextVariableName(u_long *namesz, efi_char *name, struct uuid *vendor)
199248590Smm{
200248590Smm	return (unsupported(__func__));
201248590Smm}
202248590Smm
203248590Smmstatic efi_status
204248590SmmSetVariable(efi_char *name, struct uuid *vendor, uint32_t attrs, u_long datasz,
205248590Smm    void *data)
206248590Smm{
207248590Smm	return (unsupported(__func__));
208248590Smm}
209248590Smm
210248590Smmstatic efi_status
211248590SmmGetNextHighMonotonicCount(uint32_t *high)
212248590Smm{
213248590Smm	static uint32_t counter = 0;
214248590Smm
215248590Smm	*high = counter++;
216248590Smm	return (0);
217248590Smm}
218248590Smm
219248590Smmstatic efi_status
220248590SmmResetSystem(enum efi_reset type, efi_status status, u_long datasz,
221248590Smm    efi_char *data)
222248590Smm{
223248590Smm	return (unsupported(__func__));
224248590Smm}
225248590Smm
226248590Smmint
227248590Smmski_init_stubs(struct bootinfo *bi)
228{
229	struct efi_md *memp;
230
231	/* Describe the SKI memory map. */
232	bi->bi_memmap = (u_int64_t)(bi + 1);
233	bi->bi_memmap_size = 4 * sizeof(struct efi_md);
234	bi->bi_memdesc_size = sizeof(struct efi_md);
235	bi->bi_memdesc_version = 1;
236
237	memp = (struct efi_md *)bi->bi_memmap;
238
239	memp[0].md_type = EFI_MD_TYPE_PALCODE;
240	memp[0].md_phys = 0x100000;
241	memp[0].md_virt = NULL;
242	memp[0].md_pages = (4L*1024*1024)>>12;
243	memp[0].md_attr = EFI_MD_ATTR_WB | EFI_MD_ATTR_RT;
244
245	memp[1].md_type = EFI_MD_TYPE_FREE;
246	memp[1].md_phys = 5L*1024*1024;
247	memp[1].md_virt = NULL;
248	memp[1].md_pages = (128L*1024*1024)>>12;
249	memp[1].md_attr = EFI_MD_ATTR_WB;
250
251	memp[2].md_type = EFI_MD_TYPE_FREE;
252	memp[2].md_phys = 4L*1024*1024*1024;
253	memp[2].md_virt = NULL;
254	memp[2].md_pages = (64L*1024*1024)>>12;
255	memp[2].md_attr = EFI_MD_ATTR_WB;
256
257	memp[3].md_type = EFI_MD_TYPE_IOPORT;
258	memp[3].md_phys = 0xffffc000000;
259	memp[3].md_virt = NULL;
260	memp[3].md_pages = (64L*1024*1024)>>12;
261	memp[3].md_attr = EFI_MD_ATTR_UC;
262
263	bi->bi_systab = (u_int64_t)&efi_systab;
264
265	sal_stub_init();
266	acpi_stub_init();
267
268	return (0);
269}
270