xref: /netbsd/sys/arch/amd64/amd64/prekern.c (revision dac17ed7)
1*dac17ed7Smlelstv /*	$NetBSD: prekern.c,v 1.6 2022/08/21 14:05:52 mlelstv Exp $	*/
2dafff276Smaxv 
3dafff276Smaxv /*
4dafff276Smaxv  * Copyright (c) 2017 The NetBSD Foundation, Inc. All rights reserved.
5dafff276Smaxv  *
6dafff276Smaxv  * This code is derived from software contributed to The NetBSD Foundation
7dafff276Smaxv  * by Maxime Villard.
8dafff276Smaxv  *
9dafff276Smaxv  * Redistribution and use in source and binary forms, with or without
10dafff276Smaxv  * modification, are permitted provided that the following conditions
11dafff276Smaxv  * are met:
12dafff276Smaxv  * 1. Redistributions of source code must retain the above copyright
13dafff276Smaxv  *    notice, this list of conditions and the following disclaimer.
14dafff276Smaxv  * 2. Redistributions in binary form must reproduce the above copyright
15dafff276Smaxv  *    notice, this list of conditions and the following disclaimer in the
16dafff276Smaxv  *    documentation and/or other materials provided with the distribution.
17dafff276Smaxv  *
18dafff276Smaxv  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19dafff276Smaxv  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20dafff276Smaxv  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21dafff276Smaxv  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22dafff276Smaxv  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23dafff276Smaxv  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24dafff276Smaxv  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25dafff276Smaxv  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26dafff276Smaxv  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27dafff276Smaxv  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28dafff276Smaxv  * POSSIBILITY OF SUCH DAMAGE.
29dafff276Smaxv  */
30dafff276Smaxv 
31dafff276Smaxv #include <sys/cdefs.h>
32dafff276Smaxv 
33dafff276Smaxv #include "opt_realmem.h"
34dafff276Smaxv 
35dafff276Smaxv #include <sys/param.h>
36dafff276Smaxv #include <sys/systm.h>
37dafff276Smaxv #include <sys/kernel.h>
38dafff276Smaxv #include <sys/cpu.h>
39dafff276Smaxv #include <sys/conf.h>
40dafff276Smaxv 
41dafff276Smaxv #include <uvm/uvm.h>
42dafff276Smaxv #include <machine/pmap.h>
43*dac17ed7Smlelstv #include <machine/pmap_private.h>
44dafff276Smaxv #include <machine/bootinfo.h>
45dafff276Smaxv #include <machine/cpufunc.h>
46dafff276Smaxv 
47*dac17ed7Smlelstv #include <x86/bootspace.h>
48*dac17ed7Smlelstv 
49dafff276Smaxv #include <dev/isa/isareg.h>
50dafff276Smaxv #include <machine/isa_machdep.h>
51dafff276Smaxv 
525becad1bSmaxv #define PREKERN_API_VERSION	2
53b1771f5aSmaxv 
54dafff276Smaxv struct prekern_args {
55b1771f5aSmaxv 	int version;
56dafff276Smaxv 	int boothowto;
57dafff276Smaxv 	void *bootinfo;
58dafff276Smaxv 	void *bootspace;
59dafff276Smaxv 	int esym;
60dafff276Smaxv 	int biosextmem;
61dafff276Smaxv 	int biosbasemem;
62dafff276Smaxv 	int cpuid_level;
63dafff276Smaxv 	uint32_t nox_flag;
64dafff276Smaxv 	uint64_t PDPpaddr;
65dafff276Smaxv 	vaddr_t atdevbase;
66dafff276Smaxv 	vaddr_t lwp0uarea;
67dafff276Smaxv 	paddr_t first_avail;
68dafff276Smaxv };
69dafff276Smaxv 
70dafff276Smaxv void main(void);
71d2e55ab6Smaxv void init_slotspace(void);
72dafff276Smaxv void init_x86_64(paddr_t);
73dafff276Smaxv 
74dafff276Smaxv static void prekern_copy_args(struct prekern_args *);
75dafff276Smaxv static void prekern_unmap(void);
76dafff276Smaxv int start_prekern(struct prekern_args *);
77dafff276Smaxv 
78dafff276Smaxv static void
prekern_copy_args(struct prekern_args * pkargs)79dafff276Smaxv prekern_copy_args(struct prekern_args *pkargs)
80dafff276Smaxv {
81dafff276Smaxv 	extern int boothowto;
82dafff276Smaxv 	extern struct bootinfo bootinfo;
83dafff276Smaxv 	extern struct bootspace bootspace;
84dafff276Smaxv 	extern int esym;
85dafff276Smaxv 	extern int biosextmem;
86dafff276Smaxv 	extern int biosbasemem;
87dafff276Smaxv 	extern int cpuid_level;
88dafff276Smaxv 	extern uint32_t nox_flag;
89dafff276Smaxv 	extern uint64_t PDPpaddr;
90dafff276Smaxv 	extern vaddr_t lwp0uarea;
91dafff276Smaxv 
92dafff276Smaxv 	boothowto = pkargs->boothowto;
93dafff276Smaxv 	memcpy(&bootinfo, pkargs->bootinfo, sizeof(bootinfo));
94dafff276Smaxv 	memcpy(&bootspace, pkargs->bootspace, sizeof(bootspace));
95dafff276Smaxv 	esym = pkargs->esym;
96dafff276Smaxv 
97dafff276Smaxv #ifndef REALEXTMEM
98dafff276Smaxv 	biosextmem = pkargs->biosextmem;
99dafff276Smaxv #else
100dafff276Smaxv 	biosextmem = REALEXTMEM;
101dafff276Smaxv #endif
102dafff276Smaxv 
103dafff276Smaxv #ifndef REALBASEMEM
104dafff276Smaxv 	biosbasemem = pkargs->biosbasemem;
105dafff276Smaxv #else
106dafff276Smaxv 	biosbasemem = REALBASEMEM;
107dafff276Smaxv #endif
108dafff276Smaxv 
109dafff276Smaxv 	cpuid_level = pkargs->cpuid_level;
110dafff276Smaxv 	nox_flag = pkargs->nox_flag;
111dafff276Smaxv 	PDPpaddr = pkargs->PDPpaddr;
112dafff276Smaxv 	atdevbase = pkargs->atdevbase;
113dafff276Smaxv 	lwp0uarea = pkargs->lwp0uarea;
114dafff276Smaxv }
115dafff276Smaxv 
116dafff276Smaxv static void
prekern_unmap_pte(void)117f2ce2829Smaxv prekern_unmap_pte(void)
118f2ce2829Smaxv {
119f2ce2829Smaxv 	extern struct bootspace bootspace;
120f2ce2829Smaxv 	pd_entry_t *pdir = (pd_entry_t *)bootspace.pdir;
121f2ce2829Smaxv 
122f2ce2829Smaxv 	/* Unmap the prekern recursive PTE slot. */
123f2ce2829Smaxv 	pdir[509] = 0;
124f2ce2829Smaxv 	tlbflushg();
125f2ce2829Smaxv }
126f2ce2829Smaxv 
127f2ce2829Smaxv static void
prekern_unmap(void)128dafff276Smaxv prekern_unmap(void)
129dafff276Smaxv {
130f2ce2829Smaxv 	/* Unmap the prekern itself. */
131dafff276Smaxv 	L4_BASE[0] = 0;
132dafff276Smaxv 	tlbflushg();
133dafff276Smaxv }
134dafff276Smaxv 
135dafff276Smaxv /*
136dafff276Smaxv  * The prekern jumps here.
137dafff276Smaxv  */
138dafff276Smaxv int
start_prekern(struct prekern_args * pkargs)139dafff276Smaxv start_prekern(struct prekern_args *pkargs)
140dafff276Smaxv {
141dafff276Smaxv 	paddr_t first_avail;
142dafff276Smaxv 
143b1771f5aSmaxv 	if (pkargs->version != PREKERN_API_VERSION) {
144b1771f5aSmaxv 		return -1;
145b1771f5aSmaxv 	}
146b1771f5aSmaxv 
147dafff276Smaxv 	prekern_copy_args(pkargs);
148dafff276Smaxv 	first_avail = pkargs->first_avail;
149dafff276Smaxv 
150f2ce2829Smaxv 	prekern_unmap_pte();
151d2e55ab6Smaxv 	init_slotspace();
152dafff276Smaxv 	init_x86_64(first_avail);
153dafff276Smaxv 	prekern_unmap();
154dafff276Smaxv 
155dafff276Smaxv 	main();
156dafff276Smaxv 
157dafff276Smaxv 	panic("main returned");
158dafff276Smaxv 
159b1771f5aSmaxv 	return 0;
160dafff276Smaxv }
161