1*1a9cdd37SRoger Pau Monné /* 2*1a9cdd37SRoger Pau Monné * Copyright (c) 2004 Christian Limpach. 3*1a9cdd37SRoger Pau Monné * Copyright (c) 2004-2006,2008 Kip Macy 4*1a9cdd37SRoger Pau Monné * Copyright (c) 2013 Roger Pau Monné <roger.pau@citrix.com> 5*1a9cdd37SRoger Pau Monné * All rights reserved. 6*1a9cdd37SRoger Pau Monné * 7*1a9cdd37SRoger Pau Monné * Redistribution and use in source and binary forms, with or without 8*1a9cdd37SRoger Pau Monné * modification, are permitted provided that the following conditions 9*1a9cdd37SRoger Pau Monné * are met: 10*1a9cdd37SRoger Pau Monné * 1. Redistributions of source code must retain the above copyright 11*1a9cdd37SRoger Pau Monné * notice, this list of conditions and the following disclaimer. 12*1a9cdd37SRoger Pau Monné * 2. Redistributions in binary form must reproduce the above copyright 13*1a9cdd37SRoger Pau Monné * notice, this list of conditions and the following disclaimer in the 14*1a9cdd37SRoger Pau Monné * documentation and/or other materials provided with the distribution. 15*1a9cdd37SRoger Pau Monné * 16*1a9cdd37SRoger Pau Monné * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND 17*1a9cdd37SRoger Pau Monné * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*1a9cdd37SRoger Pau Monné * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*1a9cdd37SRoger Pau Monné * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20*1a9cdd37SRoger Pau Monné * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21*1a9cdd37SRoger Pau Monné * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22*1a9cdd37SRoger Pau Monné * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23*1a9cdd37SRoger Pau Monné * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24*1a9cdd37SRoger Pau Monné * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25*1a9cdd37SRoger Pau Monné * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*1a9cdd37SRoger Pau Monné * SUCH DAMAGE. 27*1a9cdd37SRoger Pau Monné */ 28*1a9cdd37SRoger Pau Monné 29*1a9cdd37SRoger Pau Monné #include <sys/cdefs.h> 30*1a9cdd37SRoger Pau Monné __FBSDID("$FreeBSD$"); 31*1a9cdd37SRoger Pau Monné 32*1a9cdd37SRoger Pau Monné #include <sys/param.h> 33*1a9cdd37SRoger Pau Monné #include <sys/bus.h> 34*1a9cdd37SRoger Pau Monné #include <sys/kernel.h> 35*1a9cdd37SRoger Pau Monné #include <sys/reboot.h> 36*1a9cdd37SRoger Pau Monné #include <sys/systm.h> 37*1a9cdd37SRoger Pau Monné #include <sys/lock.h> 38*1a9cdd37SRoger Pau Monné #include <sys/rwlock.h> 39*1a9cdd37SRoger Pau Monné 40*1a9cdd37SRoger Pau Monné #include <vm/vm.h> 41*1a9cdd37SRoger Pau Monné #include <vm/vm_extern.h> 42*1a9cdd37SRoger Pau Monné #include <vm/vm_kern.h> 43*1a9cdd37SRoger Pau Monné #include <vm/vm_page.h> 44*1a9cdd37SRoger Pau Monné #include <vm/vm_map.h> 45*1a9cdd37SRoger Pau Monné #include <vm/vm_object.h> 46*1a9cdd37SRoger Pau Monné #include <vm/vm_pager.h> 47*1a9cdd37SRoger Pau Monné #include <vm/vm_param.h> 48*1a9cdd37SRoger Pau Monné 49*1a9cdd37SRoger Pau Monné #include <xen/xen-os.h> 50*1a9cdd37SRoger Pau Monné #include <xen/hypervisor.h> 51*1a9cdd37SRoger Pau Monné 52*1a9cdd37SRoger Pau Monné /* Native initial function */ 53*1a9cdd37SRoger Pau Monné extern u_int64_t hammer_time(u_int64_t, u_int64_t); 54*1a9cdd37SRoger Pau Monné /* Xen initial function */ 55*1a9cdd37SRoger Pau Monné uint64_t hammer_time_xen(start_info_t *, uint64_t); 56*1a9cdd37SRoger Pau Monné 57*1a9cdd37SRoger Pau Monné /* 58*1a9cdd37SRoger Pau Monné * First function called by the Xen PVH boot sequence. 59*1a9cdd37SRoger Pau Monné * 60*1a9cdd37SRoger Pau Monné * Set some Xen global variables and prepare the environment so it is 61*1a9cdd37SRoger Pau Monné * as similar as possible to what native FreeBSD init function expects. 62*1a9cdd37SRoger Pau Monné */ 63*1a9cdd37SRoger Pau Monné uint64_t 64*1a9cdd37SRoger Pau Monné hammer_time_xen(start_info_t *si, uint64_t xenstack) 65*1a9cdd37SRoger Pau Monné { 66*1a9cdd37SRoger Pau Monné uint64_t physfree; 67*1a9cdd37SRoger Pau Monné uint64_t *PT4 = (u_int64_t *)xenstack; 68*1a9cdd37SRoger Pau Monné uint64_t *PT3 = (u_int64_t *)(xenstack + PAGE_SIZE); 69*1a9cdd37SRoger Pau Monné uint64_t *PT2 = (u_int64_t *)(xenstack + 2 * PAGE_SIZE); 70*1a9cdd37SRoger Pau Monné int i; 71*1a9cdd37SRoger Pau Monné 72*1a9cdd37SRoger Pau Monné xen_domain_type = XEN_PV_DOMAIN; 73*1a9cdd37SRoger Pau Monné vm_guest = VM_GUEST_XEN; 74*1a9cdd37SRoger Pau Monné 75*1a9cdd37SRoger Pau Monné if ((si == NULL) || (xenstack == 0)) { 76*1a9cdd37SRoger Pau Monné HYPERVISOR_shutdown(SHUTDOWN_crash); 77*1a9cdd37SRoger Pau Monné } 78*1a9cdd37SRoger Pau Monné 79*1a9cdd37SRoger Pau Monné /* We use 3 pages of xen stack for the boot pagetables */ 80*1a9cdd37SRoger Pau Monné physfree = xenstack + 3 * PAGE_SIZE - KERNBASE; 81*1a9cdd37SRoger Pau Monné 82*1a9cdd37SRoger Pau Monné /* Setup Xen global variables */ 83*1a9cdd37SRoger Pau Monné HYPERVISOR_start_info = si; 84*1a9cdd37SRoger Pau Monné HYPERVISOR_shared_info = 85*1a9cdd37SRoger Pau Monné (shared_info_t *)(si->shared_info + KERNBASE); 86*1a9cdd37SRoger Pau Monné 87*1a9cdd37SRoger Pau Monné /* 88*1a9cdd37SRoger Pau Monné * Setup some misc global variables for Xen devices 89*1a9cdd37SRoger Pau Monné * 90*1a9cdd37SRoger Pau Monné * XXX: Devices that need these specific variables should 91*1a9cdd37SRoger Pau Monné * be rewritten to fetch this info by themselves from the 92*1a9cdd37SRoger Pau Monné * start_info page. 93*1a9cdd37SRoger Pau Monné */ 94*1a9cdd37SRoger Pau Monné xen_store = (struct xenstore_domain_interface *) 95*1a9cdd37SRoger Pau Monné (ptoa(si->store_mfn) + KERNBASE); 96*1a9cdd37SRoger Pau Monné 97*1a9cdd37SRoger Pau Monné /* 98*1a9cdd37SRoger Pau Monné * Use the stack Xen gives us to build the page tables 99*1a9cdd37SRoger Pau Monné * as native FreeBSD expects to find them (created 100*1a9cdd37SRoger Pau Monné * by the boot trampoline). 101*1a9cdd37SRoger Pau Monné */ 102*1a9cdd37SRoger Pau Monné for (i = 0; i < (PAGE_SIZE / sizeof(uint64_t)); i++) { 103*1a9cdd37SRoger Pau Monné /* Each slot of the level 4 pages points to the same level 3 page */ 104*1a9cdd37SRoger Pau Monné PT4[i] = ((uint64_t)&PT3[0]) - KERNBASE; 105*1a9cdd37SRoger Pau Monné PT4[i] |= PG_V | PG_RW | PG_U; 106*1a9cdd37SRoger Pau Monné 107*1a9cdd37SRoger Pau Monné /* Each slot of the level 3 pages points to the same level 2 page */ 108*1a9cdd37SRoger Pau Monné PT3[i] = ((uint64_t)&PT2[0]) - KERNBASE; 109*1a9cdd37SRoger Pau Monné PT3[i] |= PG_V | PG_RW | PG_U; 110*1a9cdd37SRoger Pau Monné 111*1a9cdd37SRoger Pau Monné /* The level 2 page slots are mapped with 2MB pages for 1GB. */ 112*1a9cdd37SRoger Pau Monné PT2[i] = i * (2 * 1024 * 1024); 113*1a9cdd37SRoger Pau Monné PT2[i] |= PG_V | PG_RW | PG_PS | PG_U; 114*1a9cdd37SRoger Pau Monné } 115*1a9cdd37SRoger Pau Monné load_cr3(((uint64_t)&PT4[0]) - KERNBASE); 116*1a9cdd37SRoger Pau Monné 117*1a9cdd37SRoger Pau Monné /* Now we can jump into the native init function */ 118*1a9cdd37SRoger Pau Monné return (hammer_time(0, physfree)); 119*1a9cdd37SRoger Pau Monné } 120