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