Changeset View
Standalone View
sys/arm64/xen/xen-dt.c
- This file was added.
/* | |||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD | |||||
* | |||||
* Copyright (c) 2014 Julien Grall | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND | |||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
*/ | |||||
#include <sys/cdefs.h> | |||||
__FBSDID("$FreeBSD$"); | |||||
#include <sys/param.h> | |||||
#include <sys/systm.h> | |||||
#include <sys/bus.h> | |||||
#include <sys/kernel.h> | |||||
#include <sys/pcpu.h> | |||||
#include <sys/rman.h> | |||||
#include <sys/module.h> | |||||
#include <vm/vm.h> | |||||
#include <vm/pmap.h> | |||||
#include <vm/vm_page.h> | |||||
#include <dev/ofw/openfirm.h> | |||||
#include <dev/ofw/ofw_bus.h> | |||||
#include <dev/ofw/ofw_bus_subr.h> | |||||
#include <dev/fdt/fdt_common.h> | |||||
#include <xen/xen-os.h> | |||||
#include <xen/xen_intr.h> | |||||
#include <xen/hypervisor.h> | |||||
#include <xen/interface/vcpu.h> | |||||
#include <xen/features.h> | |||||
struct shared_info *HYPERVISOR_shared_info = NULL; | |||||
DPCPU_DEFINE(struct vcpu_info, vcpu_local_info); | |||||
DPCPU_DEFINE(struct vcpu_info *, vcpu_info); | |||||
struct xen_softc | |||||
{ | |||||
struct resource *xen_res[2]; | |||||
void *intr_cookie; | |||||
}; | |||||
#define XEN_RESOURCE_IRQ_EVTCHN 0 | |||||
#define XEN_RESOURCE_MEMORY_GNTTAB 1 | |||||
static struct resource_spec xen_spec[] = { | |||||
/* RF_SHAREABLE ??? */ | |||||
{ SYS_RES_IRQ, 0, RF_ACTIVE }, /* Event channel IRQ */ | |||||
{ SYS_RES_MEMORY, 0, 0}, /* Grant-table */ | |||||
{ -1, 0, 0 }, | |||||
}; | |||||
struct xen_softc *xen_sc = NULL; | |||||
mhorne: This doesn't seem to be used by this file. Software contexts are not typically tracked in this… | |||||
ehem_freebsd_m5p.comAuthorUnsubmitted Done Inline ActionsThis could be due to having been written in 2015. I'll take a look at this. ehem_freebsd_m5p.com: This could be due to having been written in 2015. I'll take a look at this. | |||||
static void xen_init(void *arg __unused) | |||||
mhorneUnsubmitted Done Inline Actionsxen_init() is too general a name for this function. This looks to be equivalent to xen_hvm_init_shared_page_info() from x86/xen/hvm.c. Since arm64 will be HVM only (yes?), I guess maybe xen_init_shared_page(). mhorne: `xen_init()` is too general a name for this function. This looks to be equivalent to… | |||||
ehem_freebsd_m5p.comAuthorUnsubmitted Done Inline ActionsI suppose it could be renamed. I can't help noting this is a static function so as long as the name doesn't collide with another function in the file it should be okay. ehem_freebsd_m5p.com: I suppose it could be renamed. I can't help noting this is a static function so as long as the… | |||||
ehem_freebsd_m5p.comAuthorUnsubmitted Done Inline ActionsThing is, this really is highly similar to xen_hvm_init_shared_info_page() in sys/x86/xen/hvm.c. So similar they could fairly readily be merged. @royger does xen_hvm_init_shared_info_page() actually need to be called on resume on x86? Can it instead simply be called once during sysinit? (if yes, then this could be a static function in common.c; if no, then this could be a global in common.c) @royger and @julien_xen.org opinion on the differences between xen_hvm_init_shared_info_page() versus what is currently xen_init()? xen_hvm_init_shared_info_page() instead does a malloc(PAGE_SIZE, M_XENHVM, M_NOWAIT), versus the vm_page_alloc() here. ehem_freebsd_m5p.com: Thing is, this really is //highly similar// to xen_hvm_init_shared_info_page() in… | |||||
ehem_freebsd_m5p.comAuthorUnsubmitted Done Inline Actionsehem_freebsd_m5p.com: Now part of D28982 and the function is `xen_handle_shared_info()`. This implementation… | |||||
{ | |||||
int rc; | |||||
struct xen_add_to_physmap xatp; | |||||
vm_page_t shared_info; | |||||
vm_paddr_t shared_paddr; | |||||
if (!xen_domain()) | |||||
return; | |||||
shared_info = vm_page_alloc(NULL, 0, VM_ALLOC_NOOBJ | VM_ALLOC_ZERO); | |||||
KASSERT(shared_info != NULL, ("Unable to allocate shared page\n")); | |||||
shared_paddr = VM_PAGE_TO_PHYS(shared_info); | |||||
HYPERVISOR_shared_info = pmap_mapdev_attr(shared_paddr, PAGE_SIZE, | |||||
VM_MEMATTR_XEN); | |||||
xatp.domid = DOMID_SELF; | |||||
xatp.idx = 0; | |||||
xatp.space = XENMAPSPACE_shared_info; | |||||
xatp.gpfn = shared_paddr >> PAGE_SHIFT; | |||||
rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp); | |||||
KASSERT(rc == 0, ("Unable to map shared info\n")); | |||||
} | |||||
SYSINIT(xen_init, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, xen_init, NULL); | |||||
roygerUnsubmitted Done Inline ActionsI'm not convinced this should be tied to the usage of device-tree (as it's in the same file). An Arm guest booting off ACPI would also require the registration of the shared_info page, and hence this routine should be in a separate file. royger: I'm not convinced this should be tied to the usage of device-tree (as it's in the same file). | |||||
ehem_freebsd_m5p.comAuthorUnsubmitted Done Inline ActionsThat likely means merging this portion with D29874. I noticed xen_early_init() didn't fit in xen-dt.c, but hadn't noticed xen_init() might also need to be broken off. Hmm. ehem_freebsd_m5p.com: That likely means merging this portion with D29874. I noticed xen_early_init() didn't fit in… | |||||
ehem_freebsd_m5p.comAuthorUnsubmitted Done Inline ActionsI'm kind of doubtful Xen is likely to support anything besides device-tree on ARM. The boot method I've been using has been to use a Tianocore build as something akin to a first-stage bootloader (domain configuration file: kernel = "/usr/share/xen/XEN_EFI.fd"). In this situation Tianocore preserves the device-tree as an ACPI table, so this does function in presence of ACPI/UEFI support. That though is not an argument against breaking this function off and into a separate file. Other issue is why isn't HYPERVISOR_shared_info in a common file somewhere... ehem_freebsd_m5p.com: I'm kind of doubtful Xen is likely to support anything besides device-tree on ARM. The boot… | |||||
julien_xen.orgUnsubmitted Done Inline ActionsXen *does* provide both ACPI and Device-Tree. Although, the support for ACPI in Dom0 is less mature than the guest support. If an admin wants to use Xen + FreeBSD on server, then he/she will have to use ACPI because quite a few servers don't provide DT (or doesn't guarantee to be fully functional). Therefore, I think we should avoid to rely too much on DT in port for FreeBSD. Note this is not a request to add support for ACPI as part of this work. julien_xen.org: Xen *does* provide both ACPI and Device-Tree. Although, the support for ACPI in Dom0 is less… | |||||
ehem_freebsd_m5p.comAuthorUnsubmitted Done Inline Actionsehem_freebsd_m5p.com: As above, now merged into the function `xen_handle_shared_info()` in D28982. Hopefully the… | |||||
static int | |||||
xen_probe(device_t dev) | |||||
{ | |||||
if (!ofw_bus_is_compatible(dev, "xen,xen")) | |||||
return (ENXIO); | |||||
device_set_desc(dev, "Xen ARM device-tree"); | |||||
return (BUS_PROBE_DEFAULT); | |||||
} | |||||
static int | |||||
xen_intr_filter(void *trap_frame) | |||||
{ | |||||
xen_intr_handle_upcall(trap_frame); | |||||
return (FILTER_HANDLED); | |||||
} | |||||
static int | |||||
xen_attach(device_t dev) | |||||
{ | |||||
struct xen_softc *sc; | |||||
struct vcpu_register_vcpu_info info; | |||||
struct vcpu_info *vcpu_info; | |||||
int rc, cpu; | |||||
if (xen_sc != NULL) | |||||
return (ENXIO); | |||||
sc = device_get_softc(dev); | |||||
/* TODO: Move to a proper function */ | |||||
vcpu_info = DPCPU_PTR(vcpu_local_info); | |||||
cpu = PCPU_GET(cpuid); | |||||
info.mfn = vtophys(vcpu_info) >> PAGE_SHIFT; | |||||
info.offset = vtophys(vcpu_info) - trunc_page(vtophys(vcpu_info)); | |||||
rc = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info); | |||||
KASSERT(rc == 0, ("Unable to register cpu %u\n", cpu)); | |||||
DPCPU_SET(vcpu_info, vcpu_info); | |||||
roygerUnsubmitted Not Done Inline ActionsSame here, the reigstration of the vcpu_info shouldn't be done here, the more that this will only be executed for the BSP, and you need the vcpu_info to be registered for each vCPU on the system royger: Same here, the reigstration of the vcpu_info shouldn't be done here, the more that this will… | |||||
if (bus_alloc_resources(dev, xen_spec, sc->xen_res)) { | |||||
device_printf(dev, "could not allocate resources\n"); | |||||
return (ENXIO); | |||||
} | |||||
xen_sc = sc; | |||||
/* Setup and enable the event channel interrupt */ | |||||
if (bus_setup_intr(dev, sc->xen_res[XEN_RESOURCE_IRQ_EVTCHN], | |||||
INTR_TYPE_MISC|INTR_MPSAFE, | |||||
xen_intr_filter, NULL, sc, &sc->intr_cookie)) | |||||
{ | |||||
bus_release_resources(dev, xen_spec, sc->xen_res); | |||||
device_printf(dev, "could not setup event channel interrupt\n"); | |||||
return (ENXIO); | |||||
} | |||||
return (0); | |||||
} | |||||
static device_method_t xen_methods[] = { | |||||
DEVMETHOD(device_probe, xen_probe), | |||||
DEVMETHOD(device_attach, xen_attach), | |||||
{ 0, 0 } | |||||
}; | |||||
static driver_t xen_driver = { | |||||
"xen-dt", | |||||
xen_methods, | |||||
sizeof(struct xen_softc), | |||||
}; | |||||
static devclass_t xen_devclass; | |||||
DRIVER_MODULE(xen, simplebus, xen_driver, xen_devclass, 0, 0); | |||||
DRIVER_MODULE(xen, ofwbus, xen_driver, xen_devclass, 0, 0); |
This doesn't seem to be used by this file. Software contexts are not typically tracked in this way, but instead obtained from the device_t structure via device_get_softc(9).