# Makefile for GeekOS kernel, userspace, and tools
 # Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $Revision: 1.33 $
+# $Revision: 1.34 $
 
 # This is free software.  You are permitted to use,
 # redistribute, and modify it as specified in the file "COPYING".
 VMM_C_SRCS :=   vm_guest.c \
                svm.c svm_handler.c vmm.c vmm_util.c vmm_ctrl_regs.c \
                vmcb.c vmm_mem.c vmm_paging.c vmm_io.c vmm_debug.c svm_io.c \
-               vmm_intr.c vmm_irq.c\
+               vmm_intr.c vmm_time.c\
                vmm_shadow_paging.c vm_guest_mem.c  \
                 vm_dev.c vmm_dev_mgr.c \
 #\
 
 VMM_OBJS := $(VMM_C_OBJS) $(VMM_ASM_OBJS)
 
-DEVICE_C_SRCS :=  keyboard.c nvram.c timer.c simple_pic.c 8259a.c
+DEVICE_C_SRCS :=  keyboard.c nvram.c timer.c simple_pic.c 8259a.c 8254.c
 
 DEVICE_C_OBJS := $(DEVICE_C_SRCS:%.c=devices/%.o)
 
 CC_KERNEL_OPTS := -g -DGEEKOS -I$(PROJECT_ROOT)/include
 
 # Flags used for VMM C source files
-CC_VMM_OPTS := -g -I$(PROJECT_ROOT)/include -D__V3VEE__
+CC_VMM_OPTS := -g -I$(PROJECT_ROOT)/include -D__V3VEE__ -D__V3_32BIT__
 
 # Flags used for VMM C ASM files
 NASM_VMM_OPTS := -I$(PROJECT_ROOT)/src/palacios/ -f elf $(EXTRA_NASM_OPTS)
 
 geekos/idt.o: ../src/geekos/idt.c ../include/geekos/kassert.h \
   ../include/geekos/screen.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/defs.h ../include/geekos/idt.h \
   ../include/geekos/int.h ../include/geekos/serial.h \
   ../include/geekos/irq.h ../include/geekos/string.h \
   ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/io.h ../include/geekos/debug.h
 geekos/int.o: ../src/geekos/int.c ../include/geekos/idt.h \
   ../include/geekos/int.h ../include/geekos/kassert.h \
   ../include/geekos/screen.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/defs.h ../include/geekos/serial.h \
   ../include/geekos/irq.h ../include/geekos/string.h \
   ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/io.h ../include/geekos/debug.h \
   ../include/geekos/cpu.h
 geekos/trap.o: ../src/geekos/trap.c ../include/geekos/idt.h \
   ../include/geekos/int.h ../include/geekos/kassert.h \
   ../include/geekos/screen.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/defs.h ../include/geekos/kthread.h \
   ../include/geekos/list.h ../include/geekos/trap.h \
   ../include/geekos/serial.h ../include/geekos/irq.h \
   ../include/geekos/string.h ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/io.h ../include/geekos/debug.h
 geekos/irq.o: ../src/geekos/irq.c ../include/geekos/kassert.h \
   ../include/geekos/screen.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/idt.h ../include/geekos/int.h \
   ../include/geekos/defs.h ../include/geekos/io.h ../include/geekos/irq.h \
   ../include/geekos/debug.h ../include/geekos/serial.h \
   ../include/geekos/string.h ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
 geekos/io.o: ../src/geekos/io.c ../include/geekos/io.h \
   ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h
 geekos/blockdev.o: ../src/geekos/blockdev.c ../include/geekos/errno.h \
   ../include/geekos/screen.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/string.h ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/malloc.h ../include/geekos/int.h \
   ../include/geekos/kassert.h ../include/geekos/defs.h \
   ../include/geekos/kthread.h ../include/geekos/list.h \
   ../include/geekos/irq.h ../include/geekos/int.h \
   ../include/geekos/kassert.h ../include/geekos/screen.h \
   ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/defs.h ../include/geekos/string.h \
   ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/io.h ../include/geekos/errno.h \
   ../include/geekos/malloc.h ../include/geekos/timer.h \
   ../include/geekos/kthread.h ../include/geekos/list.h \
   ../include/geekos/ide.h
 geekos/keyboard.o: ../src/geekos/keyboard.c ../include/geekos/kthread.h \
   ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/list.h ../include/geekos/kassert.h \
   ../include/geekos/screen.h ../include/geekos/fmtout.h \
   ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/irq.h ../include/geekos/int.h \
   ../include/geekos/defs.h ../include/geekos/io.h \
   ../include/geekos/keyboard.h
 geekos/screen.o: ../src/geekos/screen.c \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/kassert.h ../include/geekos/screen.h \
   ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
   ../include/geekos/io.h ../include/geekos/int.h ../include/geekos/defs.h \
   ../include/geekos/debug.h ../include/geekos/serial.h \
   ../include/geekos/irq.h ../include/geekos/string.h \
   ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
 geekos/timer.o: ../src/geekos/timer.c \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/limits.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/limits.h \
   ../include/geekos/io.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/int.h ../include/geekos/kassert.h \
   ../include/geekos/screen.h ../include/geekos/fmtout.h \
   ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/defs.h ../include/geekos/irq.h \
   ../include/geekos/kthread.h ../include/geekos/list.h \
   ../include/geekos/timer.h ../include/geekos/serial.h \
   ../include/geekos/string.h ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/debug.h
 geekos/mem.o: ../src/geekos/mem.c ../include/geekos/defs.h \
   ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/kassert.h ../include/geekos/screen.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/bootinfo.h ../include/geekos/gdt.h \
   ../include/geekos/int.h ../include/geekos/malloc.h \
   ../include/geekos/string.h ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/mem.h ../include/geekos/list.h \
   ../include/geekos/paging.h ../include/geekos/serial.h \
   ../include/geekos/irq.h ../include/geekos/io.h \
   ../include/geekos/debug.h
 geekos/crc32.o: ../src/geekos/crc32.c ../include/geekos/crc32.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/kassert.h ../include/geekos/screen.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/serial.h ../include/geekos/irq.h \
   ../include/geekos/int.h ../include/geekos/defs.h \
   ../include/geekos/string.h ../include/geekos/../libc/string.h \
   ../include/geekos/io.h ../include/geekos/debug.h
 geekos/gdt.o: ../src/geekos/gdt.c ../include/geekos/kassert.h \
   ../include/geekos/screen.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/segment.h ../include/geekos/int.h \
   ../include/geekos/defs.h ../include/geekos/tss.h \
   ../include/geekos/gdt.h ../include/libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/debug.h ../include/geekos/serial.h \
   ../include/geekos/irq.h ../include/geekos/string.h \
   ../include/geekos/../libc/string.h ../include/geekos/io.h
 geekos/tss.o: ../src/geekos/tss.c ../include/geekos/kassert.h \
   ../include/geekos/screen.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/defs.h ../include/geekos/gdt.h \
   ../include/geekos/segment.h ../include/geekos/string.h \
   ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/tss.h ../include/geekos/serial.h \
   ../include/geekos/irq.h ../include/geekos/int.h ../include/geekos/io.h \
   ../include/geekos/debug.h
 geekos/segment.o: ../src/geekos/segment.c ../include/geekos/kassert.h \
   ../include/geekos/screen.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/string.h ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/tss.h ../include/geekos/segment.h
 geekos/bget.o: ../src/geekos/bget.c ../include/geekos/string.h \
   ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/kassert.h ../include/geekos/screen.h \
   ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/bget.h
 geekos/malloc.o: ../src/geekos/malloc.c ../include/geekos/screen.h \
   ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/int.h ../include/geekos/kassert.h \
   ../include/geekos/defs.h ../include/geekos/bget.h \
   ../include/geekos/malloc.h
 geekos/synch.o: ../src/geekos/synch.c ../include/geekos/kthread.h \
   ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/list.h ../include/geekos/kassert.h \
   ../include/geekos/screen.h ../include/geekos/fmtout.h \
   ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/int.h ../include/geekos/defs.h \
   ../include/geekos/synch.h
 geekos/kthread.o: ../src/geekos/kthread.c ../include/geekos/kassert.h \
   ../include/geekos/screen.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/defs.h ../include/geekos/int.h \
   ../include/geekos/mem.h ../include/geekos/list.h \
   ../include/geekos/paging.h ../include/geekos/bootinfo.h \
   ../include/geekos/symbol.h ../include/geekos/string.h \
   ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/kthread.h ../include/geekos/malloc.h \
   ../include/geekos/serial.h ../include/geekos/irq.h \
   ../include/geekos/io.h ../include/geekos/debug.h
   ../include/geekos/irq.h ../include/geekos/int.h \
   ../include/geekos/kassert.h ../include/geekos/screen.h \
   ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/defs.h ../include/geekos/string.h \
   ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/io.h ../include/geekos/reboot.h \
   ../include/geekos/gdt.h ../include/geekos/idt.h
 geekos/reboot.o: ../src/geekos/reboot.c ../include/geekos/reboot.h \
   ../include/libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
 geekos/paging.o: ../src/geekos/paging.c ../include/geekos/string.h \
   ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/int.h ../include/geekos/kassert.h \
   ../include/geekos/screen.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/defs.h ../include/geekos/idt.h \
   ../include/geekos/kthread.h ../include/geekos/list.h \
   ../include/geekos/mem.h ../include/geekos/paging.h \
   ../include/geekos/serial.h ../include/geekos/irq.h \
   ../include/geekos/int.h ../include/geekos/kassert.h \
   ../include/geekos/screen.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/defs.h ../include/geekos/string.h \
   ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/io.h
-geekos/vmm_stubs.o: ../src/geekos/vmm_stubs.c ../include/geekos/vmm_stubs.h \
-  ../include/geekos/mem.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/geekos/defs.h ../include/geekos/list.h \
-  ../include/geekos/kassert.h ../include/geekos/screen.h \
-  ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
-  ../include/geekos/paging.h ../include/geekos/bootinfo.h \
-  ../include/geekos/malloc.h ../include/geekos/serial.h \
-  ../include/geekos/irq.h ../include/geekos/int.h \
-  ../include/geekos/string.h ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/geekos/io.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_mem.h ../include/palacios/vmm_types.h \
-  ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
-  ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
-  ../include/palacios/vmm_string.h ../include/palacios/vmm_irq.h
-geekos/vm.o: ../src/geekos/vm.c ../include/geekos/vmm_stubs.h \
-  ../include/geekos/mem.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/geekos/defs.h ../include/geekos/list.h \
-  ../include/geekos/kassert.h ../include/geekos/screen.h \
-  ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
-  ../include/geekos/paging.h ../include/geekos/bootinfo.h \
-  ../include/geekos/malloc.h ../include/palacios/vmm.h \
-  ../include/palacios/vm_guest.h ../include/palacios/vmm_mem.h \
-  ../include/palacios/vmm_types.h ../include/palacios/vmm_io.h \
-  ../include/palacios/vmm_util.h ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
-  ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_irq.h ../include/geekos/debug.h \
-  ../include/geekos/serial.h ../include/geekos/irq.h \
-  ../include/geekos/int.h ../include/geekos/string.h \
-  ../include/geekos/../libc/string.h ../include/geekos/io.h \
-  ../include/geekos/vm.h ../include/devices/nvram.h \
-  ../include/palacios/vm_dev.h ../include/devices/timer.h \
-  ../include/devices/simple_pic.h ../include/devices/8259a.h \
-  ../include/devices/keyboard.h
 geekos/main.o: ../src/geekos/main.c ../include/geekos/bootinfo.h \
   ../include/geekos/string.h ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/screen.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/geekos/mem.h ../include/geekos/defs.h \
   ../include/geekos/list.h ../include/geekos/kassert.h \
   ../include/geekos/paging.h ../include/geekos/crc32.h \
   ../include/geekos/debug.h ../include/geekos/vm.h \
   ../include/geekos/gdt.h ../include/geekos/vmm_stubs.h
 common/fmtout.o: ../src/common/fmtout.c \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
   ../include/geekos/string.h ../include/geekos/../libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/limits.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/limits.h \
   ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h
 common/string.o: ../src/common/string.c ../include/libc/fmtout.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
   ../include/libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
 common/memmove.o: ../src/common/memmove.c ../include/libc/string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
-palacios/vm_guest.o: ../src/palacios/vm_guest.c ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_mem.h ../include/palacios/vmm_types.h \
-  ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
-  ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
-  ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_irq.h
-palacios/svm.o: ../src/palacios/svm.c ../include/palacios/svm.h \
-  ../include/palacios/vmm_util.h ../include/palacios/vmm_types.h \
-  ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_mem.h ../include/palacios/vmm_io.h \
-  ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
-  ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_irq.h ../include/palacios/vmcb.h \
-  ../include/palacios/svm_handler.h ../include/palacios/vmm_debug.h \
-  ../include/palacios/vm_guest_mem.h ../include/palacios/vmm_emulate.h
-palacios/svm_handler.o: ../src/palacios/svm_handler.c \
-  ../include/palacios/svm_handler.h ../include/palacios/svm.h \
-  ../include/palacios/vmm_util.h ../include/palacios/vmm_types.h \
-  ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_mem.h ../include/palacios/vmm_io.h \
-  ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
-  ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_irq.h ../include/palacios/vmcb.h \
-  ../include/palacios/vm_guest_mem.h ../include/palacios/vmm_emulate.h \
-  ../include/palacios/vmm_ctrl_regs.h ../include/palacios/svm_io.h
-palacios/vmm.o: ../src/palacios/vmm.c ../include/palacios/vmm.h \
-  ../include/palacios/vm_guest.h ../include/palacios/vmm_mem.h \
-  ../include/palacios/vmm_types.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
-  ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
-  ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_irq.h ../include/palacios/svm.h \
-  ../include/palacios/vmcb.h ../include/palacios/vmx.h \
-  ../include/palacios/vmcs.h ../include/palacios/vmcs_gen.h
-palacios/vmm_util.o: ../src/palacios/vmm_util.c ../include/palacios/vmm_util.h \
-  ../include/palacios/vmm_types.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_mem.h ../include/palacios/vmm_io.h \
-  ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
-  ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_irq.h
-palacios/vmm_ctrl_regs.o: ../src/palacios/vmm_ctrl_regs.c \
-  ../include/palacios/vmm_mem.h ../include/palacios/vmm_types.h \
-  ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
-  ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
-  ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_irq.h ../include/palacios/vmcb.h \
-  ../include/palacios/vmm_emulate.h ../include/palacios/vm_guest_mem.h \
-  ../include/palacios/vmm_ctrl_regs.h
-palacios/vmcb.o: ../src/palacios/vmcb.c ../include/palacios/vmcb.h \
-  ../include/palacios/vmm_types.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vm_guest.h ../include/palacios/vmm_mem.h \
-  ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
-  ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
-  ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_irq.h ../include/palacios/vmm.h
-palacios/vmm_mem.o: ../src/palacios/vmm_mem.c ../include/palacios/vmm_mem.h \
-  ../include/palacios/vmm_types.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
-  ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
-  ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_irq.h
-palacios/vmm_paging.o: ../src/palacios/vmm_paging.c \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_types.h \
-  ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm_mem.h ../include/palacios/vmm_util.h \
-  ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_io.h ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_intr.h ../include/palacios/vmm_dev_mgr.h \
-  ../include/palacios/vmm_list.h ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_irq.h ../include/palacios/vm_guest_mem.h
-palacios/vmm_io.o: ../src/palacios/vmm_io.c ../include/palacios/vmm_io.h \
-  ../include/palacios/vmm_types.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm_util.h ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_mem.h ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
-  ../include/palacios/vmm_irq.h
-palacios/vmm_debug.o: ../src/palacios/vmm_debug.c ../include/palacios/vmm_debug.h \
-  ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_mem.h ../include/palacios/vmm_types.h \
-  ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
-  ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
-  ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_irq.h
-palacios/svm_io.o: ../src/palacios/svm_io.c ../include/palacios/svm_io.h \
-  ../include/palacios/vm_guest.h ../include/palacios/vmm_mem.h \
-  ../include/palacios/vmm_types.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
-  ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
-  ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_irq.h ../include/palacios/vmcb.h \
-  ../include/palacios/vmm.h ../include/palacios/vmm_ctrl_regs.h \
-  ../include/palacios/vmm_emulate.h ../include/palacios/vm_guest_mem.h
-palacios/vmm_intr.o: ../src/palacios/vmm_intr.c ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_types.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_mem.h ../include/palacios/vmm_io.h \
-  ../include/palacios/vmm_util.h ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_dev_mgr.h \
-  ../include/palacios/vmm_list.h ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_irq.h
-palacios/vmm_irq.o: ../src/palacios/vmm_irq.c
-palacios/vmm_shadow_paging.o: ../src/palacios/vmm_shadow_paging.c \
-  ../include/palacios/vmm_shadow_paging.h ../include/palacios/vmm_util.h \
-  ../include/palacios/vmm_types.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_mem.h \
-  ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_io.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
-  ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_irq.h ../include/palacios/vm_guest_mem.h
-palacios/vm_guest_mem.o: ../src/palacios/vm_guest_mem.c \
-  ../include/palacios/vm_guest_mem.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_mem.h ../include/palacios/vmm_types.h \
-  ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
-  ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
-  ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_irq.h ../include/palacios/vmm.h
-palacios/vm_dev.o: ../src/palacios/vm_dev.c ../include/palacios/vm_dev.h \
-  ../include/palacios/vmm_types.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm_list.h ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm.h \
-  ../include/palacios/vm_guest.h ../include/palacios/vmm_mem.h \
-  ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
-  ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_irq.h
-palacios/vmm_dev_mgr.o: ../src/palacios/vmm_dev_mgr.c ../include/palacios/vm_dev.h \
-  ../include/palacios/vmm_types.h ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm_list.h ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_mem.h ../include/palacios/vmm_io.h \
-  ../include/palacios/vmm_util.h ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_irq.h ../include/palacios/vmm.h
-devices/keyboard.o: ../src/devices/keyboard.c ../include/devices/keyboard.h \
-  ../include/palacios/vm_dev.h ../include/palacios/vmm_types.h \
-  ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm_list.h ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/geekos/io.h \
-  ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_mem.h ../include/palacios/vmm_io.h \
-  ../include/palacios/vmm_util.h ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_irq.h
-devices/nvram.o: ../src/devices/nvram.c ../include/devices/nvram.h \
-  ../include/palacios/vm_dev.h ../include/palacios/vmm_types.h \
-  ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm_list.h ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm.h \
-  ../include/palacios/vm_guest.h ../include/palacios/vmm_mem.h \
-  ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
-  ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_irq.h
-devices/timer.o: ../src/devices/timer.c ../include/devices/timer.h \
-  ../include/palacios/vm_dev.h ../include/palacios/vmm_types.h \
-  ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm_list.h ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm.h \
-  ../include/palacios/vm_guest.h ../include/palacios/vmm_mem.h \
-  ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
-  ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm_irq.h
-devices/simple_pic.o: ../src/devices/simple_pic.c ../include/devices/simple_pic.h \
-  ../include/palacios/vm_dev.h ../include/palacios/vmm_types.h \
-  ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm_list.h ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_mem.h ../include/palacios/vmm_io.h \
-  ../include/palacios/vmm_util.h ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_irq.h
-devices/8259a.o: ../src/devices/8259a.c ../include/devices/8259a.h \
-  ../include/palacios/vm_dev.h ../include/palacios/vmm_types.h \
-  ../include/geekos/ktypes.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
-  ../include/palacios/vmm_list.h ../include/palacios/vmm_string.h \
-  /home/pdinda/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
-  ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_intr.h \
-  ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
-  ../include/palacios/vmm_mem.h ../include/palacios/vmm_io.h \
-  ../include/palacios/vmm_util.h ../include/palacios/vmm_shadow_paging.h \
-  ../include/palacios/vmm_paging.h ../include/palacios/vmm_irq.h
+  /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
 
--- /dev/null
+#ifndef __8254_H
+#define __8254_H
+
+#include <palacios/vm_dev.h>
+
+
+
+struct vm_device * create_pit();
+
+
+
+
+
+#endif
 
 int hook_irq_stub(struct guest_info * info, int irq);
 int ack_irq(int irq);
 
+
+unsigned int get_cpu_khz();
+
 void Init_Stubs();
+
+
+
+
+
+
+
+
+
+#if 0
+
+# define do_div(n,base) ({                                     \
+       uint32_t __base = (base);                               \
+       uint32_t __rem;                                         \
+       __rem = ((uint64_t)(n)) % __base;                       \
+       (n) = ((uint64_t)(n)) / __base;                         \
+       __rem;                                                  \
+ })
+
+#else
+
+/*
+ * do_div() is NOT a C function. It wants to return
+ * two values (the quotient and the remainder), but
+ * since that doesn't work very well in C, what it
+ * does is:
+ *
+ * - modifies the 64-bit dividend _in_place_
+ * - returns the 32-bit remainder
+ *
+ * This ends up being the most efficient "calling
+ * convention" on x86.
+ */
+#define do_div(n,base) ({                                   \
+      unsigned long __upper, __low, __high, __mod, __base;   \
+      __base = (base);                                      \
+      asm("":"=a" (__low), "=d" (__high):"A" (n));          \
+      __upper = __high;                                             \
+      if (__high) {                                         \
+       __upper = __high % (__base);                         \
+       __high = __high / (__base);                          \
+      }                                                                        \
+      asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \
+      asm("":"=A" (n):"a" (__low),"d" (__high));                       \
+      __mod;                                                           \
+    })
+
+#endif
+
+
+
+
+
+
 #endif
 
 #include <palacios/vmm_shadow_paging.h>
 #include <palacios/vmm_intr.h>
 #include <palacios/vmm_dev_mgr.h>
-#include <palacios/vmm_irq.h>
+#include <palacios/vmm_time.h>
 
 
 typedef ullong_t v3_reg_t;
 
 
 struct vm_ctrl_ops {
-  int (*raise_irq)(struct guest_info * info, int irq, int error_code);
+  int (*raise_irq)(struct guest_info * info, int irq);
 };
 
 
 
   uint_t cpl;
 
+
   struct shadow_map mem_map;
 
+  struct vm_time time_state;
   
   vm_page_mode_t page_mode;
   struct shadow_page_state shdw_pg_state;
   // This structure is how we get interrupts for the guest
   struct vm_intr intr_state;
 
-
-  // struct vmm_irq_map irq_map;
   vmm_io_map_t io_map;
   // device_map
 
 
   struct vm_ctrl_ops vm_ops;
 
+
+
   void * vmm_data;
 };
 
 
   } while (0)                                          \
 
 
-
+/*
 #define V3_Malloc(type, var, size)                     \
   do {                                                 \
     extern struct vmm_os_hooks * os_hooks;             \
       var = (type)(os_hooks)->malloc(size);            \
     }                                                  \
   } while (0)                                          \
+*/
 
+#define V3_Malloc(size) ({                     \
+      extern struct vmm_os_hooks * os_hooks;   \
+      void * var = 0;                          \
+      if ((os_hooks) && (os_hooks)->malloc) {  \
+       var = (os_hooks)->malloc(size);         \
+      }                                                \
+      var;                                     \
+    })
 
 // We need to check the hook structure at runtime to ensure its SAFE
 #define V3_Free(addr)                                  \
     }                                                  \
   } while (0)                                          \
 
+#define V3_CPU_KHZ(khz)                                        \
+  do {                                                 \
+    extern struct vmm_os_hooks * os_hooks;             \
+    if ((os_hooks) && (os_hooks)->get_cpu_khz) {       \
+      khz = (os_hooks)->get_cpu_khz();                 \
+    }                                                  \
+  } while (0)                                          \
+
 
 /* ** */
 
   int (*hook_interrupt)(struct guest_info * info, int irq);
   int (*ack_irq)(int irq);
 
+
+  unsigned int (*get_cpu_khz)();
+
   // Do we need this here?
-  void (*snprintf)(char * dst, char * format, int len, ...);
+  //  void (*snprintf)(char * dst, char * format, int len, ...);
+
+
 
   void (*start_kernel_thread)(); // include pointer to function
 };
 
   
   uint_t num_mem_hooks;
   struct list_head mem_hooks;
-  /*
-  uint_t num_irq_hooks;
-  struct list_head irq_hooks;
-  */
+
 };
 
 
   struct vm_device * dev;
 
   // Do not touch anything below this  
-  /*
-    struct dev_io_hook *dev_next, *dev_prev;
-    struct dev_io_hook *mgr_next, *mgr_prev;
-  */
+
   struct list_head dev_list;
   struct list_head mgr_list;
 };
   struct list_head mgr_list;
 };
 
-/*
-struct dev_irq_hook {
-  uint_t irq;
-
-  int (*handler)(uint_t irq, struct vm_device * dev);
-
-  struct vm_device * dev;
-
-  struct list_head dev_list;
-  struct list_head mgr_list;
-};
 
-*/
 // Registration of devices
 
 //
 int dev_mgr_remove_device(struct vmm_dev_mgr * mgr, struct vm_device * dev);
 
 
-/*
-  int dev_mgr_add_io_hook(struct vmm_dev_mgr * mgr, struct dev_io_hook * hook);
-  int dev_mgr_remove_io_hook(struct vmm_dev_mgr * mgr, struct dev_io_hook * hook);
-  int dev_add_io_hook(struct vmm_dev_mgr * mgr, struct dev_io_hook * hook);
-  int dev_remove_io_hook(struct vmm_dev_mgr * mgr, struct dev_io_hook * hook);
-  struct dev_io_hook * dev_find_io_hook(struct vm_device * dev, ushort_t port);
-  struct dev_io_hook * dev_mgr_find_io_hook(struct vmm_dev_mgr * mgr, ushort_t port)
-*/
+
 
 void PrintDebugDevMgr(struct vmm_dev_mgr * mgr);
 void PrintDebugDev(struct vm_device * dev);
 
 /*
  * This is where we do the hideous X86 instruction parsing among other things
  * We can parse out the instruction prefixes, as well as decode the operands 
-
  */
 
 
-/* JRL: Some of this was taken from the Xen sources... 
- *
+/* 
+ * JRL: Some of this was taken from the Xen sources... 
  */
 
 #define PACKED __attribute__((packed))
 
 
 struct guest_info;
 
+
+
+/* We need a way to allow the APIC/PIC to decide when they are supposed to receive interrupts...
+ * Maybe a notification call when they have been turned on, to deliver irqs to them...
+ * We can rehook the guest raise_irq op, to the appropriate controller
+ */
+
+
 struct vm_intr {
 
   /* We need to rework the exception state, to handle stacking */
 };
 
 
-int raise_irq(struct guest_info * info, int irq, int error_code);
+int raise_irq(struct guest_info * info, int irq);
 int hook_irq(struct guest_info * info, int irq);
 
 struct intr_ctrl_ops {
   int (*intr_pending)(void * private_data);
   int (*get_intr_number)(void * private_data);
-  int (*raise_intr)(void * private_data, int irq, int error_code);
+  int (*raise_intr)(void * private_data, int irq);
   int (*begin_irq)(void * private_data, int irq);
 };
 
 
+++ /dev/null
-#ifndef __VMM_IRQ_H
-#define __VMM_IRQ_H
-
-#if 0
-#include <palacios/vmm_types.h>
-
-
-struct vmm_irq_hook;
-
-
-
-
-struct vmm_irq_hook {
-  uint_t irq;
-  void * private_data;
-
-  int(*handler)(uint_t irq, void * private_data);
-
-  struct vmm_irq_hook *next, *prev;
-};
-
-
-void init_irq_map(struct vmm_irq_map * map);
-
-
-int hook_irq(struct vmm_irq_map * map, uint_t irq, 
-            int(*handler)(uint_t irq, void * private_data), 
-            void * private_data);
-
-
-int unhook_irq(struct vmm_irq_map * map, uint_t irq);
-
-struct vmm_irq_hook * get_irq_hook(struct vmm_irq_map * map, uint_t irq);
-
-#endif
-#endif
 
--- /dev/null
+#ifndef __VMM_TIME_H
+#define __VMM_TIME_H
+
+
+#include <palacios/vmm_types.h>
+#include <palacios/vmm_list.h>
+
+struct guest_info;
+
+struct vm_time {
+  uint32_t cpu_freq; // in kHZ
+
+  // Total number of guest run time cycles
+  ullong_t guest_tsc;
+
+  // Cache value to help calculate the guest_tsc
+  ullong_t cached_host_tsc;
+
+  // The number of cycles pending for notification to the timers
+  ullong_t pending_cycles;
+
+  // Installed Timers 
+  uint_t num_timers;
+  struct list_head timers;
+};
+
+
+struct vm_timer_ops {
+ void (*update_time)(ullong_t cpu_cycles, ullong_t cpu_freq, void * priv_data);
+
+};
+
+struct vm_timer {
+  void * private_data;
+  struct vm_timer_ops ops;
+
+  struct list_head timer_link;
+};
+
+
+void v3_init_time(struct vm_time * time_state);
+
+
+
+
+int v3_add_timer(struct guest_info * info, struct vm_timer_ops * ops, void * private_data);
+int v3_remove_timer(struct guest_info * info, struct vm_timer * timer);
+
+
+void v3_update_timers(struct guest_info * info);
+
+#endif
 
 typedef unsigned long size_t;
 
 */
+
+
+
+typedef unsigned long long uint64_t;
+typedef long long sint64_t;
+
+typedef unsigned int uint32_t;
+typedef int sint32_t;
+
 #endif
 
 void PrintTraceMemDump(unsigned char * start, int n);
 
 
+
+
+#define rdtsc(low,high)                                                \
+     __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
+
+#define rdtscl(low)                                            \
+     __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx")
+
+#if defined(__i386__)
+
+#define rdtscll(val)                           \
+     __asm__ __volatile__("rdtsc" : "=A" (val))
+
+#elif defined(__x86_64__)
+
+#define rdtscll(val) do {                                  \
+    unsigned int a,d;                                      \
+    asm volatile("rdtsc" : "=a" (a), "=d" (d));                    \
+    (val) = ((unsigned long)a) | (((unsigned long)d)<<32);  \
+  } while(0)
+
+#endif
+
+
+
+
+
+
+
+
+
+#ifdef __V3_64BIT__
+
+# define do_div(n,base) ({                                     \
+       uint32_t __base = (base);                               \
+       uint32_t __rem;                                         \
+       __rem = ((uint64_t)(n)) % __base;                       \
+       (n) = ((uint64_t)(n)) / __base;                         \
+       __rem;                                                  \
+ })
+
+#else
+
+/*
+ * do_div() is NOT a C function. It wants to return
+ * two values (the quotient and the remainder), but
+ * since that doesn't work very well in C, what it
+ * does is:
+ *
+ * - modifies the 64-bit dividend _in_place_
+ * - returns the 32-bit remainder
+ *
+ * This ends up being the most efficient "calling
+ * convention" on x86.
+ */
+#define do_div(n,base) ({ \
+       unsigned long __upper, __low, __high, __mod, __base; \
+       __base = (base); \
+       asm("":"=a" (__low), "=d" (__high):"A" (n)); \
+       __upper = __high; \
+       if (__high) { \
+               __upper = __high % (__base); \
+               __high = __high / (__base); \
+       } \
+       asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \
+       asm("":"=A" (n):"a" (__low),"d" (__high)); \
+       __mod; \
+})
+
+#endif
+
+
+
+
+
 #endif
 
--- /dev/null
+#include <devices/8254.h>
+#include <palacios/vmm.h>
+#include <palacios/vmm_time.h>
+
+// constants
+#define OSC_HZ 1193182
+
+
+/* The 8254 has three counters and one control port */
+#define CHANNEL0_PORT 0x40
+#define CHANNEL1_PORT 0x41
+#define CHANNEL2_PORT 0x42
+#define COMMAND_PORT 0x43
+
+
+#define PIT_INTR_NUM 0
+
+/* The order of these typedefs is important because the numerical values correspond to the 
+ * values coming from the io ports
+ */
+typedef enum {NOT_RUNNING, WAITING_LOBYTE, WAITING_HIBYTE, RUNNING} channel_access_state_t;
+typedef enum {LATCH_COUNT, LOBYTE_ONLY, HIBYTE_ONLY, LOBYTE_HIBYTE} channel_access_mode_t;
+typedef enum {IRQ_ON_TERM_CNT, ONE_SHOT, RATE_GEN, SQR_WAVE, SW_STROBE, HW_STROBE} channel_op_mode_t;
+
+
+struct channel {
+  channel_access_mode_t access_mode;
+  channel_access_state_t access_state;
+
+  channel_op_mode_t op_mode;
+
+  // Time til interrupt trigger 
+  ullong_t ns;
+
+  uint_t ctr;
+  uint_t prg_ctr;
+};
+
+
+struct pit {
+
+  struct channel ch_0;
+  struct channel ch_1;
+  struct channel ch_2;
+};
+
+struct pit_cmd {
+  uint_t channel     : 2;
+  uint_t access_mode : 2;
+  uint_t op_mode     : 3;
+  uint_t bcd_mode    : 1;
+};
+
+
+
+
+
+
+static void pit_update_time(ullong_t cpu_cycles, ullong_t cpu_freq, void * private_data) {
+
+  return;
+}
+
+
+
+static int pit_read_channel(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+  PrintDebug("8254 PIT: Read of PIT Channel %d\n", port - CHANNEL0_PORT);
+  return length;
+}
+
+
+
+static int pit_write_channel(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+  PrintDebug("8254 PIT: Write to PIT Channel %d\n", port - CHANNEL0_PORT);
+  return length;
+}
+
+
+static int pit_write_command(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+  struct pit * state = (struct pit *)dev->private_data;
+  struct pit_cmd * cmd = (struct pit_cmd *)src;
+
+  PrintDebug("8254 PIT: Write to PIT Command port\n");
+
+  if (length != 1) {
+    PrintDebug("8254 PIT: Write of Invalid length to command port\n");
+    return -1;
+  }
+
+  switch (cmd->channel) {
+  case 0:
+    state->ch_0.op_mode = cmd->op_mode;
+    break;
+  case 1:
+    break;
+  case 2:
+    break;
+  default:
+    break;
+  }
+
+
+  return length;
+}
+
+
+
+
+static struct vm_timer_ops timer_ops = {
+  .update_time = pit_update_time,
+};
+
+
+static int pit_init(struct vm_device * dev) {
+  dev_hook_io(dev, CHANNEL0_PORT, &pit_read_channel, &pit_write_channel);
+  dev_hook_io(dev, CHANNEL1_PORT, &pit_read_channel, &pit_write_channel);
+  dev_hook_io(dev, CHANNEL2_PORT, &pit_read_channel, &pit_write_channel);
+  dev_hook_io(dev, COMMAND_PORT, NULL, &pit_write_command);
+
+
+  v3_add_timer(dev->vm, &timer_ops, dev);
+
+  return 0;
+}
+
+static int pit_deinit(struct vm_device * dev) {
+
+  return 0;
+}
+
+
+static struct vm_device_ops dev_ops = {
+  .init = pit_init,
+  .deinit = pit_deinit,
+  .reset = NULL,
+  .start = NULL,
+  .stop = NULL,
+
+};
+
+
+struct vm_device * create_pit() {
+  struct pit * pit_state = NULL;
+  pit_state = (struct pit *)V3_Malloc(sizeof(struct pit));
+  V3_ASSERT(pit_state != NULL);
+
+  struct vm_device * dev = create_device("PIT", &dev_ops, pit_state);
+  
+  return dev;
+}
 
 static const uint_t SLAVE_PORT1 = 0xA0;
 static const uint_t SLAVE_PORT2 = 0xA1;
 
+#define IS_ICW1(x) (((x & 0x10) >> 4) == 0x1)
 #define IS_OCW2(x) (((x & 0x18) >> 3) == 0x0)
 #define IS_OCW3(x) (((x & 0x18) >> 3) == 0x1)
 
+
 struct icw1 {
   uint_t ic4    : 1;  // ICW4 has to be read
   uint_t sngl   : 1;  // single (only one PIC)
 
 
 
-static int pic_raise_intr(void * private_data, int irq, int error_code) {
+static int pic_raise_intr(void * private_data, int irq) {
   struct pic_internal * state = (struct pic_internal*)private_data;
 
   if (irq == 2) {
     irq = 9;
   }
 
-  PrintDebug("Raising irq %d in the PIC\n", irq);
+  PrintDebug("8259 PIC: Raising irq %d in the PIC\n", irq);
 
   if (irq <= 7) {
     state->master_irr |= 0x01 << irq;
   } else if ((irq > 7) && (irq < 16)) {
     state->slave_irr |= 0x01 << (irq - 7);
   } else {
-    PrintDebug("Invalid IRQ raised (%d)\n", irq);
+    PrintDebug("8259 PIC: Invalid IRQ raised (%d)\n", irq);
     return -1;
   }
 
        //state->master_isr |= (0x1 << i);
        // reset the irr
        //state->master_irr &= ~(0x1 << i);
-       PrintDebug("IRQ: %d, icw2: %x\n", i, state->master_icw2);
+       PrintDebug("8259 PIC: IRQ: %d, icw2: %x\n", i, state->master_icw2);
        return i + state->master_icw2;
       }
     } else {
 }
 
 
+
 /* The IRQ number is the number returned by pic_get_intr_number(), not the pin number */
 static int pic_begin_irq(void * private_data, int irq) {
   struct pic_internal * state = (struct pic_internal*)private_data;
     irq &= 0x7;
     irq += 8;
   } else {
+    PrintDebug("8259 PIC: Could not find IRQ to Begin\n");
     return -1;
   }
 
   return 0;
 }
 
+
 /*
 static int pic_end_irq(void * private_data, int irq) {
-
   return 0;
 }
 */
 
 int read_master_port1(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
   struct pic_internal * state = (struct pic_internal*)dev->private_data;
+
   if (length != 1) {
-    //error
+    PrintDebug("8259 PIC: Invalid Read length (rd_Master1)\n");
+    return -1;
   }
   
   if ((state->master_ocw3 & 0x03) == 0x02) {
 
 int read_master_port2(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
   struct pic_internal * state = (struct pic_internal*)dev->private_data;
+
   if (length != 1) {
-    // error
+    PrintDebug("8259 PIC: Invalid Read length (rd_Master2)\n");
+    return -1;
   }
 
   *(char *)dst = state->master_imr;
 
 int read_slave_port1(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
   struct pic_internal * state = (struct pic_internal*)dev->private_data;
+
   if (length != 1) {
-    // error
+    PrintDebug("8259 PIC: Invalid Read length (rd_Slave1)\n");
+    return -1;
   }
   
   if ((state->slave_ocw3 & 0x03) == 0x02) {
 
 int read_slave_port2(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
   struct pic_internal * state = (struct pic_internal*)dev->private_data;
+
   if (length != 1) {
-    // error
+    PrintDebug("8259 PIC: Invalid Read length  (rd_Slave2)\n");
+    return -1;
   }
 
   *(char *)dst = state->slave_imr;
   char cw = *(char *)src;
 
   if (length != 1) {
-    // error
+    PrintDebug("8259 PIC: Invalid Write length (wr_Master1)\n");
+    return -1;
   }
   
-  if (state->master_state == ICW1) {
+  if (IS_ICW1(cw)) {
     state->master_icw1 = cw;
     state->master_state = ICW2;
 
       } else if ((cw2->EOI) & (!cw2->R) && (!cw2->SL)) {
        int i;
        // Non-specific EOI
-       PrintDebug("Pre ISR = %x\n", state->master_isr);
+       PrintDebug("8259 PIC: Pre ISR = %x (wr_Master1)\n", state->master_isr);
        for (i = 0; i < 8; i++) {
          if (state->master_isr & (0x01 << i)) {
            state->master_isr &= ~(0x01 << i);
            break;
          }
        }       
-               PrintDebug("Post ISR = %x\n", state->master_isr);
+               PrintDebug("8259 PIC: Post ISR = %x (wr_Master1)\n", state->master_isr);
       } else {
-       // error;
+       PrintDebug("8259 PIC: Command not handled, or in error (wr_Master1)\n");
+       return -1;
       }
 
       state->master_ocw2 = cw;
     } else if (IS_OCW3(cw)) {
       state->master_ocw3 = cw;
     } else {
-      // error
+      PrintDebug("8259 PIC: Invalid OCW to PIC (wr_Master1)\n");
+      PrintDebug("8259 PIC: CW=%x\n", cw);
+      return -1;
     }
   } else {
-    // error
+    PrintDebug("8259 PIC: Invalid PIC State (wr_Master1)\n");
+    PrintDebug("8259 PIC: CW=%x\n", cw);
+    return -1;
   }
 
   return 1;
     char cw = *(char *)src;    
 
     if (length != 1) {
-      //error
+      PrintDebug("8259 PIC: Invalid Write length (wr_Master2)\n");
+      return -1;
     }
     
     if (state->master_state == ICW2) {
       struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1);
 
-      PrintDebug("Setting ICW2 = %x\n", cw);
+      PrintDebug("8259 PIC: Setting ICW2 = %x (wr_Master2)\n", cw);
       state->master_icw2 = cw;
 
       if (cw1->sngl == 0) {
       state->master_imr = cw;
     } else {
       // error
+      PrintDebug("8259 PIC: Invalid master PIC State (wr_Master2)\n");
+      return -1;
     }
 
     return 1;
 
   if (length != 1) {
     // error
+    PrintDebug("8259 PIC: Invalid Write length (wr_Slave1)\n");
+    return -1;
   }
 
-  if (state->slave_state == ICW1) {
+  if (IS_ICW1(cw)) {
     state->slave_icw1 = cw;
     state->slave_state = ICW2;
   } else if (state->slave_state == READY) {
       } else if ((cw2->EOI) & (!cw2->R) && (!cw2->SL)) {
        int i;
        // Non-specific EOI
-       PrintDebug("Pre ISR = %x\n", state->slave_isr);
+       PrintDebug("8259 PIC: Pre ISR = %x (wr_Slave1)\n", state->slave_isr);
        for (i = 0; i < 8; i++) {
          if (state->slave_isr & (0x01 << i)) {
            state->slave_isr &= ~(0x01 << i);
            break;
          }
        }       
-               PrintDebug("Post ISR = %x\n", state->slave_isr);
+               PrintDebug("8259 PIC: Post ISR = %x (wr_Slave1)\n", state->slave_isr);
       } else {
-       // error;
+       PrintDebug("8259 PIC: Command not handled or invalid  (wr_Slave1)\n");
+       return -1;
       }
 
       state->slave_ocw2 = cw;
       // Basically sets the IRR/ISR read flag
       state->slave_ocw3 = cw;
     } else {
-      // error
+      PrintDebug("8259 PIC: Invalid command work (wr_Slave1)\n");
+      return -1;
     }
   } else {
-    // error
+    PrintDebug("8259 PIC: Invalid State writing (wr_Slave1)\n");
+    return -1;
   }
 
   return 1;
     char cw = *(char *)src;    
 
     if (length != 1) {
-      //error
+      PrintDebug("8259 PIC: Invalid write length (wr_Slave2)\n");
+      return -1;
     }
 
     if (state->slave_state == ICW2) {
     } else if (state->slave_state == READY) {
       state->slave_imr = cw;
     } else {
-      // error
+      PrintDebug("8259 PIC: Invalid State at write (wr_Slave2)\n");
+      return -1;
     }
 
     return 1;
 
 struct vm_device * create_pic() {
   struct pic_internal * state = NULL;
-  V3_Malloc(struct pic_internal *, state, sizeof(struct pic_internal));
+  state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal));
+  V3_ASSERT(state != NULL);
 
   struct vm_device *device = create_device("8259A", &dev_ops, state);
 
 
 
 struct pic_internal {
   int pending_irq;
-  int error_code;
+
 };
 
 
   return (data->pending_irq > 0);
 }
 
-static int pic_raise_intr(void * private_data, int irq, int error_code) {
+static int pic_raise_intr(void * private_data, int irq) {
   struct pic_internal * data = (struct pic_internal *)private_data;
 
   data->pending_irq = irq;
-  data->error_code = error_code;
+
 
   return 0;
 }
 
 struct vm_device * create_simple_pic() {
   struct pic_internal * state = NULL;
-  V3_Malloc(struct pic_internal *, state, sizeof(struct pic_internal));
+  state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal));
+  V3_ASSERT(state != NULL);
 
   struct vm_device * pic_dev = create_device("Simple Pic", &dev_ops, state);
 
 
 
 struct vm_device * create_timer() {
   struct timer_state * timer = NULL;
-  V3_Malloc(struct timer_state *, timer, sizeof(struct timer_state));
+  timer = (struct timer_state *)V3_Malloc( sizeof(struct timer_state));
+  V3_ASSERT(timer != NULL);
+
   struct vm_device * dev = create_device("Timer", &dev_ops, timer);
   
   return dev;
 
 /*
  * Keyboard driver
  * Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
 
     Begin_IRQ(state);
 
-    Print("Keybaord\n");
+    //    Print("Keybaord\n");
 
     status = In_Byte(KB_CMD);
     IO_Delay();
 {
     ushort_t irqMask;
 
-    Print("Initializing keyboard...\n");
+        Print("Initializing keyboard...\n");
 
     /* Start out with no shift keys enabled. */
     s_shiftState = 0;
 
  * Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
  * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
  * Copyright (c) 2004, Iulian Neamtiu <neamtiu@cs.umd.edu>
- * $Revision: 1.35 $
+ * $Revision: 1.36 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
  */
 void Main(struct Boot_Info* bootInfo)
 {
-  struct Kernel_Thread * key_thread;
-  struct Kernel_Thread * spkr_thread;
 
-  ulong_t doIBuzz = 0;
 
   Out_Byte(0x1234,5);
   Out_Byte(0x1234,5);
   */
 #endif
 
-#if 1
+#if 0
+  {
+
+  struct Kernel_Thread * key_thread;
+  struct Kernel_Thread * spkr_thread;
+
+  ulong_t doIBuzz = 0;
+
   SerialPrint("Dumping BIOS code ffff0-fffff\n\n");
   SerialMemDump((unsigned char *)0x10fff0, 16);
   /*
   SerialPrint("Noisemaker and keyboard listener threads\n");
   key_thread = Start_Kernel_Thread(Keyboard_Listener, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false);
   spkr_thread = Start_Kernel_Thread(Buzzer, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false);
-
+  }
 #endif
 
   {
 
  * GeekOS timer interrupt support
  * Copyright (c) 2001,2003 David H. Hovemeyer <daveho@cs.umd.edu>
  * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
 #include <geekos/serial.h>
 #include <geekos/debug.h>
 
-#define HZ 100
+
+/* JRL Add a cpu frequency measurement */
+uint_t cpu_khz_freq;
+
+
+#define __SLOW_DOWN_IO "\noutb %%al,$0x80"
+
+#ifdef REALLY_SLOW_IO
+#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
+#else
+#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO
+#endif
+
+
+
+#define __OUT1(s,x) \
+static inline void out##s(unsigned x value, unsigned short port) {
+
+#define __OUT2(s,s1,s2) \
+__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
+
+#define __OUT(s,s1,x) \
+__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
+__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \
+
+
+#define __IN1(s) \
+static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
+
+#define __IN2(s,s1,s2) \
+__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
+
+#define __IN(s,s1,i...) \
+__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
+__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
+
+
+#define RETURN_TYPE unsigned char
+__IN(b,"")
+#undef RETURN_TYPE
+#define RETURN_TYPE unsigned short
+__IN(w,"")
+#undef RETURN_TYPE
+#define RETURN_TYPE unsigned int
+__IN(l,"")
+#undef RETURN_TYPE
+
+
+
+__OUT(b,"b",char)
+__OUT(w,"w",short)
+
+
+
+
+
+#if defined(__i386__)
+
+#define rdtscll(val)                            \
+     __asm__ __volatile__("rdtsc" : "=A" (val))
+
+#elif defined(__x86_64__)
+
+#define rdtscll(val) do {                                   \
+    unsigned int a,d;                                       \
+    asm volatile("rdtsc" : "=a" (a), "=d" (d));             \
+    (val) = ((unsigned long)a) | (((unsigned long)d)<<32);  \
+  } while(0)
+
+#endif
+
+#define do_div(n,base) ({                                   \
+      unsigned long __upper, __low, __high, __mod, __base;   \
+      __base = (base);                                      \
+      asm("":"=a" (__low), "=d" (__high):"A" (n));          \
+      __upper = __high;                                             \
+      if (__high) {                                         \
+       __upper = __high % (__base);                         \
+       __high = __high / (__base);                          \
+      }                                                                        \
+      asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \
+      asm("":"=A" (n):"a" (__low),"d" (__high));                       \
+      __mod;                                                           \
+    })
+
+
+/**
+ * This uses the Programmable Interval Timer that is standard on all
+ * PC-compatible systems to determine the time stamp counter frequency.
+ *
+ * This uses the speaker output (channel 2) of the PIT. This is better than
+ * using the timer interrupt output because we can read the value of the
+ * speaker with just one inb(), where we need three i/o operations for the
+ * interrupt channel. We count how many ticks the TSC does in 50 ms.
+ *
+ * Returns the detected time stamp counter frequency in KHz.
+ */
+
+
+static unsigned int 
+pit_calibrate_tsc(void)
+{
+  uint_t khz = 0;
+  ullong_t start, end;
+  //        unsigned long flags;
+  unsigned long pit_tick_rate = 1193182UL;  /* 1.193182 MHz */
+  
+  //        spin_lock_irqsave(&pit_lock, flags);
+  
+  outb((inb(0x61) & ~0x02) | 0x01, 0x61);
+  
+  outb(0xb0, 0x43);
+  outb((pit_tick_rate / (1000 / 50)) & 0xff, 0x42);
+  outb((pit_tick_rate / (1000 / 50)) >> 8, 0x42);
+  //        start = get_cycles_sync();
+  rdtscll(start);
+  while ((inb(0x61) & 0x20) == 0);
+  rdtscll(end);
+  //   end = get_cycles_sync();
+  
+  //        spin_unlock_irqrestore(&pit_lock, flags);
+  
+  
+  //  return (end - start) / 50;
+  khz = end - start;
+;
+
+  return khz / 50;
+}
+
+
+
+/* END JRL */
+
+
+
 
 
 /*
  * Ticks per second.
  * FIXME: should set this to something more reasonable, like 100.
  */
-#define TICKS_PER_SEC 18
+#define HZ 100
+//#define TICKS_PER_SEC 18
 
 /*#define DEBUG_TIMER */
 #ifdef DEBUG_TIMER
        ;
 
     /*
-     * Execute the spin loop.
+     * Execute the spin loop.xs
      * The temporary interrupt handler will overwrite the
      * loop counter when the next tick occurs.
      */
+
+
     Spin(INT_MAX);
 
+
+
     Disable_Interrupts();
 
     /*
 {
   ushort_t foo = 1193182L / HZ;
   
+  cpu_khz_freq = pit_calibrate_tsc();
+  PrintBoth("CPU KHZ=%lu\n", (ulong_t)cpu_khz_freq);
+
   PrintBoth("Initializing timer and setting to %d Hz...\n",HZ);
   
   /* Calibrate for delay loop */
 }
 
 
-#define US_PER_TICK (TICKS_PER_SEC * 1000000)
+#define US_PER_TICK (HZ * 1000000)
 
 /*
  * Spin for at least given number of microseconds.
 
 #include <devices/timer.h>
 #include <devices/simple_pic.h>
 #include <devices/8259a.h>
+#include <devices/8254.h>
 #include <devices/keyboard.h>
 
 #include <palacios/vmm_intr.h>
 #include <palacios/vmm_dev_mgr.h>
+#include <palacios/vmm_time.h>
 
 #define SPEAKER_PORT 0x61
 
-
-
-
-inline void VM_Out_Byte(ushort_t port, uchar_t value)
+static inline void VM_Out_Byte(ushort_t port, uchar_t value)
 {
     __asm__ __volatile__ (
        "outb %b0, %w1"
 /*
  * Read a byte from an I/O port.
  */
-inline uchar_t VM_In_Byte(ushort_t port)
+static inline uchar_t VM_In_Byte(ushort_t port)
 {
     uchar_t value;
 
 
 
 
+
 int IO_Read(ushort_t port, void * dst, uint_t length, void * priv_data) {
 
   if (length != 1) {
     os_hooks.paddr_to_vaddr = &Identity;
     os_hooks.hook_interrupt = &hook_irq_stub;
     os_hooks.ack_irq = &ack_irq;
- 
+    os_hooks.get_cpu_khz = &get_cpu_khz;
 
     Init_VMM(&os_hooks, &vmm_ops);
   
     /* MOVE THIS TO AN INIT GUEST ROUTINE */
     init_shadow_map(&(vm_info.mem_map));
     init_shadow_page_state(&(vm_info.shdw_pg_state));
+    v3_init_time(&(vm_info.time_state));
     vm_info.page_mode = SHADOW_PAGING;
 
     vm_info.cpu_mode = REAL;
        struct vm_device * nvram = create_nvram();
        //struct vm_device * timer = create_timer();
        struct vm_device * pic = create_pic();
-       struct vm_device * keyboard = create_keyboard();
+       //struct vm_device * keyboard = create_keyboard();
+       struct vm_device * pit= create_pit();
 
        attach_device(&(vm_info), nvram);
        //attach_device(&(vm_info), timer);
        attach_device(&(vm_info), pic);
-       attach_device(&(vm_info), keyboard);
+       attach_device(&(vm_info), pit);
+       //attach_device(&(vm_info), keyboard);
 
        PrintDebugDevMgr(&(vm_info.dev_mgr));
       }
 
 #include <geekos/vmm_stubs.h>
 #include <geekos/serial.h>
 #include <palacios/vm_guest.h>
+#include <geekos/debug.h>
+
+
+
+static inline void VM_Out_Byte(ushort_t port, uchar_t value)
+{
+    __asm__ __volatile__ (
+       "outb %b0, %w1"
+       :
+       : "a" (value), "Nd" (port)
+    );
+}
+
+/*
+ * Read a byte from an I/O port.
+ */
+static inline uchar_t VM_In_Byte(ushort_t port)
+{
+    uchar_t value;
+
+    __asm__ __volatile__ (
+       "inb %w1, %b0"
+       : "=a" (value)
+       : "Nd" (port)
+    );
+
+    return value;
+}
+
+
 
 
 void * Identity(void *addr) { return addr; };
   SerialPrint("Interrupt %d (IRQ=%d)\n", state->intNum, state->intNum - 32);
 
   if (info) {
-    info->vm_ops.raise_irq(info, state->intNum - 32, state->errorCode);
+    info->vm_ops.raise_irq(info, state->intNum - 32);
   } else {
     SerialPrint("Interrupt handler error: NULL pointer found, no action taken\n");
     End_IRQ(state);
 void Init_Stubs() {
   memset(irq_map, 0, sizeof(struct guest_info *) * 256);
 }
+
+
+unsigned int get_cpu_khz() {
+  extern uint_t cpu_khz_freq;
+
+  unsigned long  print_khz = (unsigned long)(cpu_khz_freq & 0xffffffff);
+  
+  PrintBoth("Detected %lu.%lu MHz CPU\n", print_khz / 1000, print_khz % 1000);
+
+  return cpu_khz_freq;
+}
+
+
+
+
+#if 0
+
+
+/* ------ Calibrate the TSC ------- 
+ * Return processor ticks per second / CALIBRATE_FRAC.
+ *
+ * Ported From Xen
+ */
+#define PIT_MODE 0x43
+#define PIT_CH2 0x42
+#define CLOCK_TICK_RATE 1193180 /* system crystal frequency (Hz) */
+#define CALIBRATE_FRAC  20      /* calibrate over 50ms */
+#define CALIBRATE_LATCH ((CLOCK_TICK_RATE+(CALIBRATE_FRAC/2))/CALIBRATE_FRAC)
+
+
+unsigned long long get_cpu_khz() {
+    ullong_t start, end;
+    unsigned long count;
+    unsigned long long tmp;
+    unsigned long print_tmp; 
+
+    /* Set the Gate high, disable speaker */
+    VM_Out_Byte((VM_In_Byte(0x61) & ~0x02) | 0x01, 0x61);
+
+    /*
+     * Now let's take care of CTC channel 2
+     *
+     * Set the Gate high, program CTC channel 2 for mode 0, (interrupt on
+     * terminal count mode), binary count, load 5 * LATCH count, (LSB and MSB)
+     * to begin countdown.
+     */
+    VM_Out_Byte(0xb0, PIT_MODE);           /* binary, mode 0, LSB/MSB, Ch 2 */
+    VM_Out_Byte(CALIBRATE_LATCH & 0xff, PIT_CH2); /* LSB of count */
+    VM_Out_Byte(CALIBRATE_LATCH >> 8, PIT_CH2);   /* MSB of count */
+
+    rdtscll(start);
+    for ( count = 0; (VM_In_Byte(0x61) & 0x20) == 0; count++ )
+        continue;
+    rdtscll(end);
+
+    /* Error if the CTC doesn't behave itself. */
+    if ( count == 0 ) {
+     PrintBoth("CPU Frequency Calibration Error\n");
+      return 0;
+    }
+
+    tmp = ((end - start) * (ullong_t)CALIBRATE_FRAC);
+
+    do_div(tmp, 1000);
+
+    tmp &= 0xffffffff;
+    print_tmp = (unsigned long)tmp;
+
+   PrintBoth("Detected %lu.%lu MHz CPU\n", print_tmp / 1000, print_tmp % 1000);
+    return tmp;
+}
+
+#undef PIT_CH2
+#undef PIT_MODE
+#undef CLOCK_TICK_RATE
+#undef CALIBRATE_FRAC  
+#undef CALIBRATE_LATCH 
+
+#endif
 
 
 // can we start a kernel thread here...
 int start_svm_guest(struct guest_info *info) {
-
-
+  vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+  vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
 
   PrintDebug("Launching SVM VM (vmcb=%x)\n", info->vmm_data);
   //PrintDebugVMCB((vmcb_t*)(info->vmm_data));
 
   while (1) {
+    ullong_t tmp_tsc;
 
     CLGI();
 
+    rdtscll(info->time_state.cached_host_tsc);
+    guest_ctrl->TSC_OFFSET = info->time_state.guest_tsc - info->time_state.cached_host_tsc;
     //PrintDebug("SVM Launch Args (vmcb=%x), (info=%x), (vm_regs=%x)\n", info->vmm_data,  &(info->vm_regs));
     //PrintDebug("Launching to RIP: %x\n", info->rip);
     safe_svm_launch((vmcb_t*)(info->vmm_data), &(info->vm_regs));
     //launch_svm((vmcb_t*)(info->vmm_data));
     //PrintDebug("SVM Returned\n");
-
+    rdtscll(tmp_tsc);
+    info->time_state.guest_tsc += tmp_tsc - info->time_state.cached_host_tsc;
     
 
     STGI();
 
      
     if (handle_svm_exit(info) != 0) {
-      vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+
       addr_t host_addr;
       addr_t linear_addr = 0;
 
 
 
   exit_code = guest_ctrl->exit_code;
  
-  //PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
+
+  // Disable printing io exits due to bochs debug messages
+  if (!((exit_code == VMEXIT_IOIO) && ((ushort_t)(guest_ctrl->exit_info1 >> 16) == 0x402))) {
+
+    PrintDebug("SVM Returned: Exit Code: %x \t\t(tsc=%ul)\n",exit_code, (uint_t)info->time_state.guest_tsc); 
+  }
   // PrintDebugVMCB((vmcb_t*)(info->vmm_data));
 
 
 
 struct vm_device * allocate_device() {
 
   struct vm_device * dev = NULL;
-  V3_Malloc(struct vm_device *, dev, sizeof(struct vm_device));
+  dev = (struct vm_device*)V3_Malloc(sizeof(struct vm_device));
+
+  V3_ASSERT(dev != NULL);
 
   dev->ops = NULL;
   memset(dev->name, 0, 32);
 
 #include <palacios/vmm_dev_mgr.h>
 #include <palacios/vm_guest.h>
 #include <palacios/vmm.h>
-#include <palacios/vmm_irq.h>
+
 
 extern struct vmm_os_hooks *os_hooks;
 
 }
 
 
-
-
-/* IRQ HOOKS */
-/*
-int dev_mgr_add_irq_hook(struct vmm_dev_mgr * mgr, struct dev_irq_hook * hook) {
-  list_add(&(hook->mgr_list), &(mgr->irq_hooks));
-  mgr->num_irq_hooks++;
-  return 0;
-}
-
-
-int dev_mgr_remove_irq_hook(struct vmm_dev_mgr * mgr, struct dev_irq_hook * hook) {
-  list_del(&(hook->mgr_list));
-  mgr->num_irq_hooks--;
-
-  return 0;
-}
-
-
-int dev_add_irq_hook(struct vm_device * dev, struct dev_irq_hook * hook) {
-  list_add(&(hook->dev_list), &(dev->irq_hooks));
-  dev->num_irq_hooks++;
-  return 0;
-}
-
-
-int dev_remove_irq_hook(struct vm_device * dev, struct dev_irq_hook * hook) {
-  list_del(&(hook->dev_list));
-  dev->num_irq_hooks--;
-
-  return 0;
-}
-
-
-
-
-
-struct dev_irq_hook * dev_mgr_find_irq_hook(struct vmm_dev_mgr * mgr, uint_t irq) {
-  struct dev_irq_hook * tmp;
-
-  list_for_each_entry(tmp, &(mgr->irq_hooks), mgr_list) {
-    if (tmp->irq == irq) {
-      return tmp;
-    }
-  }
-  return NULL;
-}
-
-struct dev_irq_hook * dev_find_irq_hook(struct vm_device * dev, uint_t irq) {
-  struct dev_irq_hook * tmp;
-
-  list_for_each_entry(tmp, &(dev->irq_hooks), dev_list) {
-    if (tmp->irq == irq) {
-      return tmp;
-    }
-  }
-  return NULL;
-}
-
-
-
-
-int dev_hook_irq(struct vm_device   *dev,
-                uint_t irq,
-                int (*handler)(uint_t irq, struct vm_device * dev)) {
-
-  struct dev_irq_hook *hook = os_hooks->malloc(sizeof(struct dev_irq_hook));
-  
-  if (!hook) { 
-    return -1;
-  }
-
-
-  if (hook_irq(&(dev->vm->irq_map), irq, 
-              (int (*)(uint_t, void *))handler, 
-              (void *)dev) == 0) {
-
-    hook->dev = dev;
-    hook->irq = irq;
-    hook->handler = handler;
-    
-    dev_mgr_add_irq_hook(&(dev->vm->dev_mgr), hook);
-    dev_add_irq_hook(dev, hook);
-  } else {
-    return -1;
-  }
-
-  return 0;
-}
-
-
-int dev_unhook_irq(struct vm_device * dev,
-                  uint_t irq) {
-
-  struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
-  struct dev_irq_hook * hook = dev_mgr_find_irq_hook(mgr, irq);
-
-  if (!hook) { 
-    return -1;
-  }
-
-  dev_mgr_remove_irq_hook(mgr, hook);
-  dev_remove_irq_hook(dev, hook);
-
-  return unhook_irq(&(dev->vm->irq_map), irq);
-}
-
-
-*/
-
-
-
-
-
 int attach_device(struct guest_info * vm, struct vm_device * dev) {
   struct vmm_dev_mgr *mgr= &(vm->dev_mgr);
   
                     void               *end)
 {
 
-  struct dev_mem_hook *hook;
-  V3_Malloc(struct dev_mem_hook *, hook,sizeof(struct dev_mem_hook));
-  
+  struct dev_mem_hook * hook = (struct dev_mem_hook*)V3_Malloc(sizeof(struct dev_mem_hook));
+  //  V3_Malloc(struct dev_mem_hook *, hook,sizeof(struct dev_mem_hook));
+
   if (!hook) { 
     return -1;
   }
 
-
-    
-
   /* not implemented yet
   hook_memory(vm->mem_map, 
              guest_physical_address_start, 
 
 }
 
 
-int raise_irq(struct guest_info * info, int irq, int error_code) {
+int raise_irq(struct guest_info * info, int irq) {
   // Look up PIC and resend
   V3_ASSERT(info);
   V3_ASSERT(info->intr_state.controller);
 
   //  if ((info->intr_state.controller) && 
   //  (info->intr_state.controller->raise_intr)) {
-    info->intr_state.controller->raise_intr(info->intr_state.controller_state, irq, error_code);
+    info->intr_state.controller->raise_intr(info->intr_state.controller_state, irq);
     //} else {
     // PrintDebug("There is no registered Interrupt Controller... (NULL POINTER)\n");
     // return -1;
 
+++ /dev/null
-#if 0
-#include <palacios/vmm_irq.h>
-#include <palacios/vmm.h>
-
-void init_irq_map(struct vmm_irq_map * map) {
-  map->head = NULL;
-  map->num_hooks = 0;
-}
-
-
-int add_irq_hook(struct vmm_irq_map * map, struct vmm_irq_hook * hook) {
-  if (!(map->head)) {
-    map->head = hook;
-    map->num_hooks = 1;
-    return 0;
-  } else if (map->head->irq > hook->irq) {
-    hook->next = map->head;
-
-    map->head->prev = hook;
-    map->head = hook;
-    map->num_hooks++;
-
-    return 0;
-  } else {
-    struct vmm_irq_hook * tmp_hook = map->head;
-    while ((tmp_hook->next) &&
-          (tmp_hook->next->irq <= hook->irq)) {
-      tmp_hook = tmp_hook->next;
-    }
-
-    if (tmp_hook->irq == hook->irq) {
-      return -1;
-    } else {
-      hook->prev = tmp_hook;
-      hook->next = tmp_hook->next;
-
-      if (tmp_hook->next) {
-       tmp_hook->next->prev = hook;
-      }
-
-      tmp_hook->next = hook;
-
-      map->num_hooks++;
-      return 0;
-    }
-  }
-  return -1;
-}
-
-
-int remove_irq_hook(struct vmm_irq_map * map, struct vmm_irq_hook * hook) {
-  if (map->head == hook) {
-    map->head = hook->next;
-  } else if (hook->prev) {
-    hook->prev->next = hook->next;
-  } else {
-    return -1;
-  }
-
-  if (hook->next) {
-    hook->next->prev = hook->prev;
-  }
-
-  map->num_hooks--;
-
-  return 0;
-}
-
-
-int hook_irq(struct vmm_irq_map * map, uint_t irq, 
-            int(*handler)(uint_t irq, void * private_data), 
-            void * private_data) {
-
-  struct vmm_irq_hook * hook = NULL;
-  V3_Malloc(struct vmm_irq_hook *, hook, sizeof(struct vmm_irq_hook));
-
-  if (!hook) {
-    // big problems
-    return -1;
-  }
-
-  hook->irq = irq;
-  hook->handler = handler;
-  hook->private_data = private_data;
-  hook->next = NULL;
-  hook->prev = NULL;
-  
-  if (add_irq_hook(map, hook) != 0) {
-    V3_Free(hook);
-    return -1;
-  }
-
-  return 0;
-}
-
-
-int unhook_irq(struct vmm_irq_map * map, uint_t irq) {
-  struct vmm_irq_hook * hook = get_irq_hook(map, irq);
-
-  if (!hook) {
-    return -1;
-  }
-
-  remove_irq_hook(map, hook);
-  return 0;
-}
-
-
-struct vmm_irq_hook * get_irq_hook(struct vmm_irq_map * map, uint_t irq) {
-  struct vmm_irq_hook * tmp_hook = map->head;
-  
-  while (tmp_hook) {
-    if (tmp_hook->irq == irq) {
-      return tmp_hook;
-    }
-    tmp_hook = tmp_hook->next;
-  }
-  return NULL;
-}
-
-
-#endif
 
--- /dev/null
+#include "palacios/vmm_time.h"
+#include "palacios/vmm.h"
+
+
+void v3_init_time(struct vm_time * time_state) {
+  ullong_t cpu_khz = 0;
+
+  V3_CPU_KHZ(cpu_khz);
+  time_state->cpu_freq = cpu_khz;
+
+  PrintDebug("CPU KHZ = HI=%x LO=%x\n", (uint_t)(cpu_khz >> 32), (uint_t)cpu_khz);
+ 
+  time_state->guest_tsc = 0;
+  time_state->cached_host_tsc = 0;
+  time_state->pending_cycles = 0;
+  
+  INIT_LIST_HEAD(&(time_state->timers));
+  time_state->num_timers = 0;
+}
+
+
+int v3_add_timer(struct guest_info * info, struct vm_timer_ops * ops, void * private_data) {
+  //  V3_Malloc
+
+  /*
+  list_add(&(timer->timer_link), &(info->time_state.timers));
+  info->time_state.num_timers++;
+  */
+  return 0;
+}
+
+int remove_timer(struct guest_info * info, struct vm_timer * timer) {
+  list_del(&(timer->timer_link));
+  info->time_state.num_timers--;
+
+  return 0;
+}
+
+
+void update_timers(struct guest_info * info) {
+  struct vm_timer * tmp_timer;
+  
+  list_for_each_entry(tmp_timer, &(info->time_state.timers), timer_link) {
+    tmp_timer->ops.update_time(info->time_state.pending_cycles, info->time_state.cpu_freq, tmp_timer->private_data);
+  }
+
+
+  info->time_state.pending_cycles = 0;
+}