1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright 2020 Conrad Meyer <cem@FreeBSD.org>. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/param.h> 29 #include <sys/errno.h> 30 #include <sys/tree.h> 31 32 #include <machine/vmm.h> 33 #include <x86/include/apicreg.h> 34 struct vm; 35 struct vm_hpet_cap; 36 #include <vmm/io/vioapic.h> 37 #include <vmm/io/vhpet.h> 38 39 #include <err.h> 40 #include <errno.h> 41 #include <vmmapi.h> 42 43 #include "kernemu_dev.h" 44 #include "mem.h" 45 46 static int 47 apic_handler(struct vcpu *vcpu, int dir, uint64_t addr, int size, 48 uint64_t *val, void *arg1 __unused, long arg2 __unused) 49 { 50 if (vm_readwrite_kernemu_device(vcpu, addr, (dir == MEM_F_WRITE), 51 size, val) != 0) 52 return (errno); 53 return (0); 54 } 55 56 static struct mem_range lapic_mmio = { 57 .name = "kern-lapic-mmio", 58 .base = DEFAULT_APIC_BASE, 59 .size = PAGE_SIZE, 60 .flags = MEM_F_RW | MEM_F_IMMUTABLE, 61 .handler = apic_handler, 62 63 }; 64 static struct mem_range ioapic_mmio = { 65 .name = "kern-ioapic-mmio", 66 .base = VIOAPIC_BASE, 67 .size = VIOAPIC_SIZE, 68 .flags = MEM_F_RW | MEM_F_IMMUTABLE, 69 .handler = apic_handler, 70 }; 71 static struct mem_range hpet_mmio = { 72 .name = "kern-hpet-mmio", 73 .base = VHPET_BASE, 74 .size = VHPET_SIZE, 75 .flags = MEM_F_RW | MEM_F_IMMUTABLE, 76 .handler = apic_handler, 77 }; 78 79 void 80 kernemu_dev_init(void) 81 { 82 int rc; 83 84 rc = register_mem(&lapic_mmio); 85 if (rc != 0) 86 errc(4, rc, "register_mem: LAPIC (0x%08x)", 87 (unsigned)lapic_mmio.base); 88 rc = register_mem(&ioapic_mmio); 89 if (rc != 0) 90 errc(4, rc, "register_mem: IOAPIC (0x%08x)", 91 (unsigned)ioapic_mmio.base); 92 rc = register_mem(&hpet_mmio); 93 if (rc != 0) 94 errc(4, rc, "register_mem: HPET (0x%08x)", 95 (unsigned)hpet_mmio.base); 96 } 97