#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
+#include <sys/rman.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/pcpu.h>
return (bus_release_resource(child, SYS_RES_MEMORY, res_id, res));
}
+#if defined(__arm__)
+static int
+xenpv_activate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ int err;
+ bus_addr_t paddr;
+ bus_size_t psize;
+ bus_space_handle_t vaddr;
+
+ /* On ARM, ring buffer and other pages shared with a guest must be
+ * mapped cacheable. But the Nexus is mapping them with DEVICE attribute.
+ * As every xen device is linked to xenpv, we can override the
+ * bus_activate_resource callback here.
+ */
+ if (type != SYS_RES_MEMORY)
+ return bus_generic_activate_resource(bus, child, type, rid,
+ r);
+
+ if ((err = rman_activate_resource(r)) != 0)
+ return (err);
+
+ paddr = (bus_addr_t)rman_get_start(r);
+ psize = (bus_size_t)rman_get_size(r);
+ vaddr = (bus_space_handle_t)xen_pmap((vm_offset_t)paddr,
+ (vm_size_t)psize);
+ if (vaddr == 0) {
+ rman_deactivate_resource(r);
+ return (ENOMEM);
+ }
+ rman_set_bustag(r, (void *)1);
+ rman_set_virtual(r, (void *)vaddr);
+ rman_set_bushandle(r, vaddr);
+
+ return (0);
+}
+
+static int
+xenpv_deactivate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ bus_size_t psize;
+ bus_space_handle_t vaddr;
+
+ psize = (bus_size_t)rman_get_size(r);
+ vaddr = rman_get_bushandle(r);
+
+ if (vaddr != 0) {
+ xen_unmap((vm_offset_t)vaddr, (vm_size_t)psize);
+ rman_set_virtual(r, NULL);
+ rman_set_bushandle(r, 0);
+ }
+
+ return (rman_deactivate_resource(r));
+}
+
+#endif
+
static device_method_t xenpv_methods[] = {
/* Device interface */
DEVMETHOD(device_identify, xenpv_identify),
DEVMETHOD(bus_add_child, bus_generic_add_child),
DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+#if defined(__arm__)
+ DEVMETHOD(bus_activate_resource, xenpv_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, xenpv_deactivate_resource),
+#else
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+#endif
/* Interface to allocate memory for foreign mappings */
DEVMETHOD(xenmem_alloc, xenpv_alloc_physmem),