From: Jack Lange <jarusl@cs.northwestern.edu>
Date: Sat, 7 Feb 2009 20:45:26 +0000 (-0600)
Subject: apic register definitions added
X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=bd18ee6111c1b75fa0bbd670307d1ec1c622f91f;p=palacios.releases.git

apic register definitions added
---

diff --git a/palacios/include/devices/apic_regs.h b/palacios/include/devices/apic_regs.h
new file mode 100644
index 0000000..ea1d55a
--- /dev/null
+++ b/palacios/include/devices/apic_regs.h
@@ -0,0 +1,312 @@
+/* 
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National 
+ * Science Foundation and the Department of Energy.  
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at 
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+
+struct lapic_id_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t rsvd          : 24;
+      uint_t apic_id       : 8;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+struct apic_ver_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t ver           : 8;
+      uint_t rsvd1         : 8;
+      uint_t max_lvts      : 8;
+      uint_t rsvd2         : 7;
+      uint_t ext_reg_present : 1;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
+struct ext_apic_ctrl_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t ver           : 1;
+      uint_t seoi_enable   : 1;
+      uint_t ext_id_enable : 1;
+      uint_t rsvd2         : 29;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
+struct local_vec_tbl_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t vec           : 8;
+      uint_t msg_type      : 3;
+      uint_t rsvd1         : 1;
+      uint_t del_status    : 1;
+      uint_t rsvd2         : 1;
+      uint_t rem_irr       : 1;
+      uint_t trig_mode     : 1;
+      uint_t mask          : 1;
+      uint_t tmr_mode      : 1;
+      uint_t rsvd3         : 14;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
+struct tmr_vec_tbl_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t vec           : 8;
+      uint_t rsvd          : 4;
+      uint_t del_status    : 1;
+      uint_t rsvd2         : 3;
+      uint_t mask          : 1;
+      uint_t tmr_mode      : 1;
+      uint_t rsvd3         : 14;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
+struct div_cfg_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t div_val       : 2;
+      uint_t rsvd          : 1;
+      uint_t div_val2      : 1;
+      uint_t rsvd2         : 28;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
+struct lint_vec_tbl_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t vec           : 8;
+      uint_t msg_type      : 3;
+      uint_t rsvd1         : 1;
+      uint_t del_status    : 1;
+      uint_t rsvd2         : 1;
+      uint_t rem_irr       : 1;
+      uint_t trig_mode     : 1;
+      uint_t mask          : 1;
+      uint_t rsvd3         : 15;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
+struct perf_ctr_loc_vec_tbl_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t vec           : 8;
+      uint_t msg_type      : 3;
+      uint_t rsvd1         : 1;
+      uint_t del_status    : 1;
+      uint_t rsvd2         : 3;
+      uint_t mask          : 1;
+      uint_t rsvd3         : 15;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
+struct therm_loc_vec_tbl_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t vec           : 8;
+      uint_t msg_type      : 3;
+      uint_t rsvd1         : 1;
+      uint_t del_status    : 1;
+      uint_t rsvd2         : 3;
+      uint_t mask          : 1;
+      uint_t rsvd3         : 15;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+struct err_vec_tbl_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t vec           : 8;
+      uint_t msg_type      : 3;
+      uint_t rsvd1         : 1;
+      uint_t del_status    : 1;
+      uint_t rsvd2         : 3;
+      uint_t mask          : 1;
+      uint_t rsvd3         : 15;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
+struct err_status_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t rsvd1         : 2;
+      uint_t sent_acc_err  : 1;
+      uint_t recv_acc_err  : 1;
+      uint_t rsvd2         : 1;
+      uint_t sent_ill_err  : 1;
+      uint_t recv_ill_err  : 1;
+      uint_t ill_reg_addr  : 1;
+      uint_t rsvd3         : 24;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
+struct spurious_int_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t vec           : 8;
+      uint_t apic_soft_en  : 1;
+      uint_t foc_cpu_chk   : 1;
+      uint_t rsvd1         : 22;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+struct int_cmd_reg {
+  union {
+    uint64_t val;
+
+    struct {
+      uint32_t lo;
+      uint32_t hi;
+    } __attribute__((packed));
+
+    struct {
+      uint_t vec           : 8;
+      uint_t msg_type      : 3;
+      uint_t dst_mode      : 1;
+      uint_t del_status    : 1;
+      uint_t rsvd1         : 1;
+      uint_t lvl           : 1;
+      uint_t trig_mode     : 1;
+      uint_t rem_rd_status : 2;
+      uint_t dst_shorthand : 2;
+      uint64_t rsvd2       : 36;
+      uint32_t dst         : 8;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
+struct loc_dst_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t rsvd1         : 24;
+      uint_t dst_log_id    : 8;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
+struct dst_fmt_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t rsvd1         : 28;
+      uint_t model         : 4;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
+struct arb_prio_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t arb_prio_sub  : 4;
+      uint_t arb_prio      : 4;
+      uint_t rsvd1         : 24;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
+
+
+struct task_prio_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t task_prio_sub  : 4;
+      uint_t task_prio      : 4;
+      uint_t rsvd1         : 24;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
+
+struct proc_prio_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t proc_prio_sub  : 4;
+      uint_t proc_prio      : 4;
+      uint_t rsvd1         : 24;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+struct ext_apic_feature_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t int_en_reg_cap : 1;
+      uint_t spec_eoi_cap   : 1;
+      uint_t ext_apic_id_cap: 1;
+      uint_t rsvd1          : 13;
+      uint_t ext_lvt_cnt    : 8;
+      uint_t rsvd2          : 8;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
+struct spec_eoi_reg {
+  union {
+    uint32_t val;
+    struct {
+      uint_t vec           : 8;
+      uint_t rsvd1         : 24;
+    } __attribute__((packed));
+  } __attribute__((packed));
+} __attribute__((packed));
+
+
diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c
index f899419..e143990 100644
--- a/palacios/src/devices/apic.c
+++ b/palacios/src/devices/apic.c
@@ -19,28 +19,108 @@
 
 
 #include <devices/apic.h>
+#include <devices/apic_regs.h>
 #include <palacios/vmm.h>
 #include <palacios/vmm_msr.h>
 
 #define BASE_ADDR_MSR 0x0000001B
 #define DEFAULT_BASE_ADDR 0xfee00000
 
-
-struct apic_base_addr_reg {
-  uchar_t rsvd;
-  uint_t bsc           : 1;
-  uint_t rsvd2         : 2;
-  uint_t apic_enable   : 1;
-  ullong_t base_addr   : 40;
-  uint_t rsvd3         : 12;
+#define APIC_ID_OFFSET                    0x020
+#define APIC_VERSION_OFFSET               0x030
+#define TPR_OFFSET                        0x080
+#define APR_OFFSET                        0x090
+#define PPR_OFFSET                        0x0a0
+#define EOI_OFFSET                        0x0b0
+#define REMOTE_READ_OFFSET                0x0c0
+#define LDR_OFFSET                        0x0d0
+#define DFR_OFFSET                        0x0e0
+#define SPURIOUS_INT_VEC_OFFSET           0x0f0
+#define ISR_OFFSET                        0x100   // 0x100 - 0x170
+#define TMR_OFFSET                        0x180   // 0x180 - 0x1f0
+#define IRR_OFFSET                        0x200   // 0x200 - 0x270
+#define ESR_OFFSET                        0x280
+#define INT_CMD_LO_OFFSET                 0x300
+#define INT_CMD_HI_OFFSET                 0x310
+#define TMR_LOC_VEC_TBL_OFFSET            0x320
+#define THERM_LOC_VEC_TBL_OFFSET          0x330
+#define PERF_CTR_LOC_VEC_TBL_OFFSET       0x340
+#define LINT0_VEC_TBL_OFFSET              0x350
+#define LINT1_VEC_TBL_OFFSET              0x360
+#define ERR_VEC_TBL_OFFSET                0x370
+#define TMR_INIT_CNT_OFFSET               0x380
+#define TMR_CUR_CNT_OFFSET                0x390
+#define TMR_DIV_CFG_OFFSET                0x3e0
+#define EXT_APIC_FEATURE_OFFSET           0x400
+#define EXT_APIC_CMD_OFFSET               0x410
+#define SEOI_OFFSET                       0x420
+#define IER_OFFSET                        0x480   // 0x480 - 0x4f0
+#define EXT_INT_LOC_VEC_TBL_OFFSET        0x500   // 0x500 - 0x530
+
+
+struct apic_base_addr_msr {
+  union {
+    uint64_t val;
+    struct {
+      uchar_t rsvd;
+      uint_t cpu_core      : 1;
+      uint_t rsvd2         : 2;
+      uint_t apic_enable   : 1;
+      ullong_t base_addr   : 40;
+      uint_t rsvd3         : 12;
+    } __attribute__((packed));
+  } __attribute__((packed));
 } __attribute__((packed));
 
+
+
+
 struct apic_state {
   addr_t base_addr;
 
-  v3_msr_t base_addr_reg;
+  /* MSRs */
+  v3_msr_t base_addr_msr;
+
+
+  /* memory map registers */
+
+  struct lapic_id_reg lapic_id;
+  struct apic_ver_reg apic_ver;
+  struct ext_apic_ctrl_reg ext_apic_ctrl;
+  struct local_vec_tbl_reg local_vec_tbl;
+  struct tmr_vec_tbl_reg tmr_vec_tbl;
+  struct div_cfg_reg div_cfg;
+  struct lint_vec_tbl_reg lint_vec_tbl;
+  struct perf_ctr_loc_vec_tbl_reg perf_ctr_loc_vec_tbl;
+  struct therm_loc_vec_tbl_reg therm_loc_vec_tbl;
+  struct err_vec_tbl_reg err_vec_tbl;
+  struct err_status_reg err_status;
+  struct spurious_int_reg spurious_int;
+  struct int_cmd_reg int_cmd;
+  struct loc_dst_reg loc_dst;
+  struct dst_fmt_reg dst_fmt;
+  struct arb_prio_reg arb_prio;
+  struct task_prio_reg task_prio;
+  struct proc_prio_reg proc_prio;
+  struct ext_apic_feature_reg ext_apic_feature;
+  struct spec_eoi_reg spec_eoi;
+  
+
+  uint32_t tmr_cur_cnt_reg;
+  uint32_t tmr_init_cnt_reg;
+
+
+
+  uint32_t rem_rd_data;
 
+
+  uchar_t int_req_reg[32];
+  uchar_t int_svc_reg[32];
+  uchar_t int_en_reg[32];
+  uchar_t trig_mode_reg[32];
   
+  uint32_t eoi;
+
 
 };
 
@@ -48,7 +128,7 @@ struct apic_state {
 static int read_apic_msr(uint_t msr, v3_msr_t * dst, void * priv_data) {
   struct vm_device * dev = (struct vm_device *)priv_data;
   struct apic_state * apic = (struct apic_state *)dev->private_data;
-  PrintDebug("READING APIC BASE ADDR: HI=%x LO=%x\n", apic->base_addr_reg.hi, apic->base_addr_reg.lo);
+  PrintDebug("READING APIC BASE ADDR: HI=%x LO=%x\n", apic->base_addr_msr.hi, apic->base_addr_msr.lo);
 
   return -1;
 }
@@ -65,14 +145,102 @@ static int write_apic_msr(uint_t msr, v3_msr_t src, void * priv_data) {
 
 
 static int apic_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
-  PrintDebug("Read from apic address space\n");
-  return -1;
+  struct vm_device * dev = (struct vm_device *)priv_data;
+  struct apic_state * apic = (struct apic_state *)dev->private_data;
+  addr_t reg_addr  = guest_addr - apic->base_addr;
+
+  if (length != 4) {
+    PrintError("Invalid apic readlength\n");
+    return -1;
+  }
+
+  switch (reg_addr) {
+  case APIC_ID_OFFSET:
+  case APIC_VERSION_OFFSET:
+  case TPR_OFFSET:
+  case APR_OFFSET:
+  case PPR_OFFSET:
+  case EOI_OFFSET:
+  case REMOTE_READ_OFFSET:
+  case LDR_OFFSET:
+  case DFR_OFFSET:
+  case SPURIOUS_INT_VEC_OFFSET:
+  case ISR_OFFSET:
+  case TMR_OFFSET:
+  case IRR_OFFSET:
+  case ESR_OFFSET:
+  case INT_CMD_LO_OFFSET:
+  case INT_CMD_HI_OFFSET:
+  case TMR_LOC_VEC_TBL_OFFSET:
+  case THERM_LOC_VEC_TBL_OFFSET:
+  case PERF_CTR_LOC_VEC_TBL_OFFSET:
+  case LINT0_VEC_TBL_OFFSET:
+  case LINT1_VEC_TBL_OFFSET:
+  case ERR_VEC_TBL_OFFSET:
+  case TMR_INIT_CNT_OFFSET:
+  case TMR_CUR_CNT_OFFSET:
+  case TMR_DIV_CFG_OFFSET:
+  case EXT_APIC_FEATURE_OFFSET:
+  case EXT_APIC_CMD_OFFSET:
+  case SEOI_OFFSET:
+  case IER_OFFSET:
+  case EXT_INT_LOC_VEC_TBL_OFFSET:
+  default:
+    PrintError("Read from Unhandled APIC Register: %x\n", (uint32_t)reg_addr);
+    return -1;
+  }
+  return length;
 }
 
 
 static int apic_write(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
   PrintDebug("Write to apic address space\n");
-  return -1;
+  struct vm_device * dev = (struct vm_device *)priv_data;
+  struct apic_state * apic = (struct apic_state *)dev->private_data;
+  addr_t reg_addr  = guest_addr - apic->base_addr;
+
+  if (length != 4) {
+    PrintError("Invalid apic write length\n");
+    return -1;
+  }
+
+  switch (reg_addr) {
+  case APIC_ID_OFFSET:
+  case APIC_VERSION_OFFSET:
+  case TPR_OFFSET:
+  case APR_OFFSET:
+  case PPR_OFFSET:
+  case EOI_OFFSET:
+  case REMOTE_READ_OFFSET:
+  case LDR_OFFSET:
+  case DFR_OFFSET:
+  case SPURIOUS_INT_VEC_OFFSET:
+  case ISR_OFFSET:
+  case TMR_OFFSET:
+  case IRR_OFFSET:
+  case ESR_OFFSET:
+  case INT_CMD_LO_OFFSET:
+  case INT_CMD_HI_OFFSET:
+  case TMR_LOC_VEC_TBL_OFFSET:
+  case THERM_LOC_VEC_TBL_OFFSET:
+  case PERF_CTR_LOC_VEC_TBL_OFFSET:
+  case LINT0_VEC_TBL_OFFSET:
+  case LINT1_VEC_TBL_OFFSET:
+  case ERR_VEC_TBL_OFFSET:
+  case TMR_INIT_CNT_OFFSET:
+  case TMR_CUR_CNT_OFFSET:
+  case TMR_DIV_CFG_OFFSET:
+  case EXT_APIC_FEATURE_OFFSET:
+  case EXT_APIC_CMD_OFFSET:
+  case SEOI_OFFSET:
+  case IER_OFFSET:
+  case EXT_INT_LOC_VEC_TBL_OFFSET:
+  default:
+    PrintError("Write to Unhandled APIC Register: %x\n", (uint32_t)reg_addr);
+    return -1;
+  }
+
+  return length;
 }