pv.c (52379d36a9bcfb7dbf73a581621b9ebb6d71f5c6) pv.c (cfa0b7b82fbdda56d7160569def5c6133eb045aa)
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-NetBSD
3 *
4 * Copyright (c) 2004 Christian Limpach.
5 * Copyright (c) 2004-2006,2008 Kip Macy
6 * Copyright (c) 2008 The NetBSD Foundation, Inc.
7 * Copyright (c) 2013 Roger Pau Monné <roger.pau@citrix.com>
8 * All rights reserved.

--- 111 unchanged lines hidden (view full) ---

120#ifdef SMP
121 .start_all_aps = xen_pv_start_all_aps,
122#endif
123 .msi_init = xen_msi_init,
124};
125
126static struct bios_smap xen_smap[MAX_E820_ENTRIES];
127
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-NetBSD
3 *
4 * Copyright (c) 2004 Christian Limpach.
5 * Copyright (c) 2004-2006,2008 Kip Macy
6 * Copyright (c) 2008 The NetBSD Foundation, Inc.
7 * Copyright (c) 2013 Roger Pau Monné <roger.pau@citrix.com>
8 * All rights reserved.

--- 111 unchanged lines hidden (view full) ---

120#ifdef SMP
121 .start_all_aps = xen_pv_start_all_aps,
122#endif
123 .msi_init = xen_msi_init,
124};
125
126static struct bios_smap xen_smap[MAX_E820_ENTRIES];
127
128static start_info_t *legacy_start_info;
129
130/*----------------------- Legacy PVH start_info accessors --------------------*/
131static vm_paddr_t
132legacy_get_xenstore_mfn(void)
133{
134
135 return (legacy_start_info->store_mfn);
136}
137
138static evtchn_port_t
139legacy_get_xenstore_evtchn(void)
140{
141
142 return (legacy_start_info->store_evtchn);
143}
144
145static vm_paddr_t
146legacy_get_console_mfn(void)
147{
148
149 return (legacy_start_info->console.domU.mfn);
150}
151
152static evtchn_port_t
153legacy_get_console_evtchn(void)
154{
155
156 return (legacy_start_info->console.domU.evtchn);
157}
158
159static uint32_t
160legacy_get_start_flags(void)
161{
162
163 return (legacy_start_info->flags);
164}
165
166struct hypervisor_info legacy_info = {
167 .get_xenstore_mfn = legacy_get_xenstore_mfn,
168 .get_xenstore_evtchn = legacy_get_xenstore_evtchn,
169 .get_console_mfn = legacy_get_console_mfn,
170 .get_console_evtchn = legacy_get_console_evtchn,
171 .get_start_flags = legacy_get_start_flags,
172};
173
128/*-------------------------------- Xen PV init -------------------------------*/
129/*
174/*-------------------------------- Xen PV init -------------------------------*/
175/*
130 * First function called by the Xen PVH boot sequence.
176 * First function called by the Xen legacy PVH boot sequence.
131 *
132 * Set some Xen global variables and prepare the environment so it is
133 * as similar as possible to what native FreeBSD init function expects.
134 */
135uint64_t
136hammer_time_xen(start_info_t *si, uint64_t xenstack)
137{
138 uint64_t physfree;

--- 11 unchanged lines hidden (view full) ---

150 }
151
152 xc_printf("FreeBSD PVH running on %s\n", si->magic);
153
154 /* We use 3 pages of xen stack for the boot pagetables */
155 physfree = xenstack + 3 * PAGE_SIZE - KERNBASE;
156
157 /* Setup Xen global variables */
177 *
178 * Set some Xen global variables and prepare the environment so it is
179 * as similar as possible to what native FreeBSD init function expects.
180 */
181uint64_t
182hammer_time_xen(start_info_t *si, uint64_t xenstack)
183{
184 uint64_t physfree;

--- 11 unchanged lines hidden (view full) ---

196 }
197
198 xc_printf("FreeBSD PVH running on %s\n", si->magic);
199
200 /* We use 3 pages of xen stack for the boot pagetables */
201 physfree = xenstack + 3 * PAGE_SIZE - KERNBASE;
202
203 /* Setup Xen global variables */
158 HYPERVISOR_start_info = si;
204 legacy_start_info = si;
159 HYPERVISOR_shared_info =
160 (shared_info_t *)(si->shared_info + KERNBASE);
161
162 /*
205 HYPERVISOR_shared_info =
206 (shared_info_t *)(si->shared_info + KERNBASE);
207
208 /*
163 * Setup some misc global variables for Xen devices
164 *
165 * XXX: Devices that need these specific variables should
166 * be rewritten to fetch this info by themselves from the
167 * start_info page.
168 */
169 xen_store = (struct xenstore_domain_interface *)
170 (ptoa(si->store_mfn) + KERNBASE);
171 console_page = (char *)(ptoa(si->console.domU.mfn) + KERNBASE);
172
173 /*
174 * Use the stack Xen gives us to build the page tables
175 * as native FreeBSD expects to find them (created
176 * by the boot trampoline).
177 */
178 for (i = 0; i < (PAGE_SIZE / sizeof(uint64_t)); i++) {
179 /*
180 * Each slot of the level 4 pages points
181 * to the same level 3 page

--- 15 unchanged lines hidden (view full) ---

197 PT2[i] = i * (2 * 1024 * 1024);
198 PT2[i] |= PG_V | PG_RW | PG_PS | PG_U;
199 }
200 load_cr3(((uint64_t)&PT4[0]) - KERNBASE);
201
202 /* Set the hooks for early functions that diverge from bare metal */
203 init_ops = xen_init_ops;
204 apic_ops = xen_apic_ops;
209 * Use the stack Xen gives us to build the page tables
210 * as native FreeBSD expects to find them (created
211 * by the boot trampoline).
212 */
213 for (i = 0; i < (PAGE_SIZE / sizeof(uint64_t)); i++) {
214 /*
215 * Each slot of the level 4 pages points
216 * to the same level 3 page

--- 15 unchanged lines hidden (view full) ---

232 PT2[i] = i * (2 * 1024 * 1024);
233 PT2[i] |= PG_V | PG_RW | PG_PS | PG_U;
234 }
235 load_cr3(((uint64_t)&PT4[0]) - KERNBASE);
236
237 /* Set the hooks for early functions that diverge from bare metal */
238 init_ops = xen_init_ops;
239 apic_ops = xen_apic_ops;
240 hypervisor_info = legacy_info;
205
206 /* Now we can jump into the native init function */
207 return (hammer_time(0, physfree));
208}
209
210/*-------------------------------- PV specific -------------------------------*/
211#ifdef SMP
212static bool

--- 73 unchanged lines hidden (view full) ---

286 * into FreeBSD boot options.
287 */
288static void
289xen_pv_set_env(void)
290{
291 char *cmd_line_next, *cmd_line;
292 size_t env_size;
293
241
242 /* Now we can jump into the native init function */
243 return (hammer_time(0, physfree));
244}
245
246/*-------------------------------- PV specific -------------------------------*/
247#ifdef SMP
248static bool

--- 73 unchanged lines hidden (view full) ---

322 * into FreeBSD boot options.
323 */
324static void
325xen_pv_set_env(void)
326{
327 char *cmd_line_next, *cmd_line;
328 size_t env_size;
329
294 cmd_line = HYPERVISOR_start_info->cmd_line;
295 env_size = sizeof(HYPERVISOR_start_info->cmd_line);
330 cmd_line = legacy_start_info->cmd_line;
331 env_size = sizeof(legacy_start_info->cmd_line);
296
297 /* Skip leading spaces */
298 for (; isspace(*cmd_line) && (env_size != 0); cmd_line++)
299 env_size--;
300
301 /* Replace ',' with '\0' */
302 for (cmd_line_next = cmd_line; strsep(&cmd_line_next, ",") != NULL;)
303 ;

--- 13 unchanged lines hidden (view full) ---

317{
318 Elf_Ehdr *ehdr;
319 Elf_Shdr *shdr;
320 vm_offset_t sym_end;
321 uint32_t size;
322 int i, j;
323
324 size = end;
332
333 /* Skip leading spaces */
334 for (; isspace(*cmd_line) && (env_size != 0); cmd_line++)
335 env_size--;
336
337 /* Replace ',' with '\0' */
338 for (cmd_line_next = cmd_line; strsep(&cmd_line_next, ",") != NULL;)
339 ;

--- 13 unchanged lines hidden (view full) ---

353{
354 Elf_Ehdr *ehdr;
355 Elf_Shdr *shdr;
356 vm_offset_t sym_end;
357 uint32_t size;
358 int i, j;
359
360 size = end;
325 sym_end = HYPERVISOR_start_info->mod_start != 0 ?
326 HYPERVISOR_start_info->mod_start :
327 HYPERVISOR_start_info->mfn_list;
361 sym_end = legacy_start_info->mod_start != 0 ?
362 legacy_start_info->mod_start : legacy_start_info->mfn_list;
328
329 /*
330 * Make sure the size is right headed, sym_end is just a
331 * high boundary, but at least allows us to fail earlier.
332 */
333 if ((vm_offset_t)&end + size > sym_end) {
334 xc_printf("Unable to load ELF symtab: size mismatch\n");
335 return;

--- 34 unchanged lines hidden (view full) ---

370static caddr_t
371xen_pv_parse_preload_data(u_int64_t modulep)
372{
373 caddr_t kmdp;
374 vm_ooffset_t off;
375 vm_paddr_t metadata;
376 char *envp;
377
363
364 /*
365 * Make sure the size is right headed, sym_end is just a
366 * high boundary, but at least allows us to fail earlier.
367 */
368 if ((vm_offset_t)&end + size > sym_end) {
369 xc_printf("Unable to load ELF symtab: size mismatch\n");
370 return;

--- 34 unchanged lines hidden (view full) ---

405static caddr_t
406xen_pv_parse_preload_data(u_int64_t modulep)
407{
408 caddr_t kmdp;
409 vm_ooffset_t off;
410 vm_paddr_t metadata;
411 char *envp;
412
378 if (HYPERVISOR_start_info->mod_start != 0) {
379 preload_metadata = (caddr_t)(HYPERVISOR_start_info->mod_start);
413 if (legacy_start_info->mod_start != 0) {
414 preload_metadata = (caddr_t)legacy_start_info->mod_start;
380
381 kmdp = preload_search_by_type("elf kernel");
382 if (kmdp == NULL)
383 kmdp = preload_search_by_type("elf64 kernel");
384 KASSERT(kmdp != NULL, ("unable to find kernel"));
385
386 /*
387 * Xen has relocated the metadata and the modules,
388 * so we need to recalculate it's position. This is
389 * done by saving the original modulep address and
390 * then calculating the offset with mod_start,
391 * which contains the relocated modulep address.
392 */
393 metadata = MD_FETCH(kmdp, MODINFOMD_MODULEP, vm_paddr_t);
415
416 kmdp = preload_search_by_type("elf kernel");
417 if (kmdp == NULL)
418 kmdp = preload_search_by_type("elf64 kernel");
419 KASSERT(kmdp != NULL, ("unable to find kernel"));
420
421 /*
422 * Xen has relocated the metadata and the modules,
423 * so we need to recalculate it's position. This is
424 * done by saving the original modulep address and
425 * then calculating the offset with mod_start,
426 * which contains the relocated modulep address.
427 */
428 metadata = MD_FETCH(kmdp, MODINFOMD_MODULEP, vm_paddr_t);
394 off = HYPERVISOR_start_info->mod_start - metadata;
429 off = legacy_start_info->mod_start - metadata;
395
396 preload_bootstrap_relocate(off);
397
398 boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
399 envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
400 if (envp != NULL)
401 envp += off;
402 init_static_kenv(envp, 0);

--- 30 unchanged lines hidden ---
430
431 preload_bootstrap_relocate(off);
432
433 boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
434 envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
435 if (envp != NULL)
436 envp += off;
437 init_static_kenv(envp, 0);

--- 30 unchanged lines hidden ---