2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
21 #include <devices/apic.h>
22 #include <palacios/vmm.h>
23 #include <palacios/vmm_msr.h>
25 #define BASE_ADDR_MSR 0x0000001B
26 #define DEFAULT_BASE_ADDR 0xfee00000
29 struct apic_base_addr_reg {
33 uint_t apic_enable : 1;
34 ullong_t base_addr : 40;
36 } __attribute__((packed));
41 v3_msr_t base_addr_reg;
48 static int read_apic_msr(uint_t msr, v3_msr_t * dst, void * priv_data) {
49 struct vm_device * dev = (struct vm_device *)priv_data;
50 struct apic_state * apic = (struct apic_state *)dev->private_data;
51 PrintDebug("READING APIC BASE ADDR: HI=%x LO=%x\n", apic->base_addr_reg.hi, apic->base_addr_reg.lo);
57 static int write_apic_msr(uint_t msr, v3_msr_t src, void * priv_data) {
58 // struct vm_device * dev = (struct vm_device *)priv_data;
59 // struct apic_state * apic = (struct apic_state *)dev->private_data;
61 PrintDebug("WRITING APIC BASE ADDR: HI=%x LO=%x\n", src.hi, src.lo);
67 static int apic_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
68 PrintDebug("Read from apic address space\n");
73 static int apic_write(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
74 PrintDebug("Write to apic address space\n");
79 static int apic_deinit(struct vm_device * dev) {
80 struct guest_info * info = dev->vm;
82 v3_unhook_msr(info, BASE_ADDR_MSR);
88 static int apic_init(struct vm_device * dev) {
89 struct guest_info * info = dev->vm;
90 struct apic_state * apic = (struct apic_state *)(dev->private_data);
92 apic->base_addr = DEFAULT_BASE_ADDR;
94 v3_hook_msr(info, BASE_ADDR_MSR, read_apic_msr, write_apic_msr, dev);
96 v3_hook_full_mem(info, DEFAULT_BASE_ADDR, DEFAULT_BASE_ADDR + PAGE_SIZE_4KB, apic_read, apic_write, dev);
103 static struct vm_device_ops dev_ops = {
105 .deinit = apic_deinit,
112 struct vm_device * v3_create_apic() {
113 PrintDebug("Creating APIC\n");
115 struct apic_state * apic = (struct apic_state *)V3_Malloc(sizeof(struct apic_state));
117 struct vm_device * device = v3_create_device("APIC", &dev_ops, apic);