# Makefile for GeekOS kernel, userspace, and tools
# Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $Revision: 1.34 $
+# $Revision: 1.35 $
# This is free software. You are permitted to use,
# redistribute, and modify it as specified in the file "COPYING".
VMM_OBJS := $(VMM_C_OBJS) $(VMM_ASM_OBJS)
-DEVICE_C_SRCS := keyboard.c nvram.c timer.c simple_pic.c 8259a.c 8254.c
+DEVICE_C_SRCS := generic.c keyboard.c nvram.c timer.c simple_pic.c 8259a.c 8254.c
DEVICE_C_OBJS := $(DEVICE_C_SRCS:%.c=devices/%.o)
+++ /dev/null
-geekos/idt.o: ../src/geekos/idt.c ../include/geekos/kassert.h \
- ../include/geekos/screen.h ../include/geekos/ktypes.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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/synch.h ../include/geekos/blockdev.h \
- ../include/geekos/fileio.h
-geekos/ide.o: ../src/geekos/ide.c ../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/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/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/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/blockdev.h ../include/geekos/fileio.h \
- ../include/geekos/ide.h
-geekos/keyboard.o: ../src/geekos/keyboard.c ../include/geekos/kthread.h \
- ../include/geekos/ktypes.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/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/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/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/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
-geekos/timer.o: ../src/geekos/timer.c \
- /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/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/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/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/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/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/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/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
- ../include/geekos/ktypes.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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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
-geekos/serial.o: ../src/geekos/serial.c ../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/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/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/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/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/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/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/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/bootinfo.h ../include/geekos/malloc.h \
- ../include/geekos/gdt.h ../include/geekos/segment.h \
- ../include/geekos/crc32.h ../include/geekos/serial.h \
- ../include/geekos/irq.h ../include/geekos/io.h \
- ../include/geekos/debug.h
-geekos/debug.o: ../src/geekos/debug.c ../include/geekos/debug.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/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/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/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
- ../include/geekos/io.h
-geekos/main.o: ../src/geekos/main.c ../include/geekos/bootinfo.h \
- ../include/geekos/string.h ../include/geekos/../libc/string.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/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/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/tss.h ../include/geekos/int.h \
- ../include/geekos/kthread.h ../include/geekos/trap.h \
- ../include/geekos/timer.h ../include/geekos/keyboard.h \
- ../include/geekos/io.h ../include/geekos/serial.h \
- ../include/geekos/irq.h ../include/geekos/reboot.h \
- ../include/geekos/ide.h ../include/geekos/malloc.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/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/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/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
- ../include/libc/string.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/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
--- /dev/null
+#ifndef __GENERIC_H
+#define __GENERIC_H
+
+#include <palacios/vm_dev.h>
+
+//
+// The generic device simply hooks ranges of ports, addresses, and irqs
+// if they are not already hooked
+//
+// for each hooked port, it simply executes reads and writes and the same physical port,
+// for each hooked memory range, it simply executes reads and writes on the same
+// physical memory addresses
+// for each hooked irq, it simply injects the irq into the VM
+//
+// These operations are also logged to serial (optionaly)
+//
+// If you attach a generic device *last*, you can capture all ops that are not
+// already hooked, and capture a log of VM activity with respect to them.
+//
+// The effects of using the generic device should be identical to
+// doing passthrough I/O, but with logging, and, of course, slower
+//
+
+
+// A port range is low..high, inclusive
+typedef uint_t generic_port_range_type[2];
+// A memory range is low..high, inclusive
+typedef void *generic_address_range_type[2];
+// An interrupt ory map range is low..high, inclusive
+typedef uint_t generic_irq_range_type[2];
+
+struct vm_device *create_generic(generic_port_range_type port_ranges[],
+ uint_t num_port_ranges,
+ generic_address_range_type addess_ranges[],
+ uint_t num_address_ranges,
+ generic_irq_range_type irq_ranges[],
+ uint_t num_irqranges);
+
+#endif
#include <palacios/vm_dev.h>
-
+//
+// The underlying driver needs to call this on each key that
+// it wants to inject into the VMM for delivery to a VM
+//
+void deliver_key_to_vmm(uchar_t status, uchar_t scancode);
struct vm_device *create_keyboard();
--- /dev/null
+#include <devices/generic.h>
+#include <geekos/io.h>
+#include <palacios/vmm.h>
+#include <palacios/vmm_types.h>
+
+
+
+#define GENERIC_DEBUG 1
+
+#if GENERIC_DEBUG
+#define GENERIC_DEBUG_PRINT(first, rest...) do { SerialPrint(first, ## rest ); } while (0)
+#else
+#define GENERIC_DEBUG_PRINT(first, rest...)
+#endif
+
+
+#define PORT_HOOKS 1
+#define MEM_HOOKS 0 // not yet implmented in device model
+#define IRQ_HOOKS 0 // not yet implemented in device model
+
+extern struct vmm_os_hooks *os_hooks;
+
+extern void SerialPrint(const char *format, ...);
+
+
+
+struct generic_internal {
+ generic_port_range_type *port_ranges;
+ uint_t num_port_ranges;
+ generic_address_range_type *address_ranges;
+ uint_t num_address_ranges;
+ generic_irq_range_type *irq_ranges;
+ uint_t num_irq_ranges;
+};
+
+
+
+
+
+
+
+
+int generic_reset_device(struct vm_device * dev)
+{
+ GENERIC_DEBUG_PRINT("generic: reset device\n");
+
+ return 0;
+
+}
+
+
+
+
+
+int generic_start_device(struct vm_device *dev)
+{
+ GENERIC_DEBUG_PRINT("generic: start device\n");
+ return 0;
+}
+
+
+int generic_stop_device(struct vm_device *dev)
+{
+ GENERIC_DEBUG_PRINT("generic: stop device\n");
+ return 0;
+}
+
+
+
+
+int generic_write_port(ushort_t port,
+ void * src,
+ uint_t length,
+ struct vm_device * dev)
+{
+ uint_t i;
+
+ GENERIC_DEBUG_PRINT("generic: writing 0x");
+ for (i=0;i<length;i++) {
+ GENERIC_DEBUG_PRINT("%x",((uchar_t*)src)[i]);
+ }
+ GENERIC_DEBUG_PRINT(" to port 0x%x ... ",port);
+ for (i=0;i<length;i++) {
+ Out_Byte(port,((uchar_t*)src)[i]);
+ }
+ GENERIC_DEBUG_PRINT(" done\n");
+
+ return length;
+}
+
+int generic_read_port(ushort_t port,
+ void * src,
+ uint_t length,
+ struct vm_device * dev)
+{
+ uint_t i;
+
+ GENERIC_DEBUG_PRINT("generic: reading 0x%x bytes from port 0x%x ...",length,port);
+ for (i=0;i<length;i++) {
+ ((uchar_t*)src)[i] =In_Byte(port);
+ }
+ GENERIC_DEBUG_PRINT(" done ... read 0x");
+ for (i=0;i<length;i++) {
+ GENERIC_DEBUG_PRINT("%x",((uchar_t*)src)[i]);
+ }
+ GENERIC_DEBUG_PRINT("\n");
+
+ return length;
+}
+
+
+
+int generic_interrupt(uint_t irq,
+ struct vm_device * dev)
+{
+ PrintDebug("generic: interrupt 0x%x - injecting into VM\n",irq);
+
+ dev->vm->vm_ops.raise_irq(dev->vm,irq,0);
+
+ return 0;
+
+}
+
+
+int generic_init_device(struct vm_device * dev)
+{
+ struct generic_internal *state = (struct generic_internal *) dev->private_data;
+ uint_t i,j;
+
+ GENERIC_DEBUG_PRINT("generic: init_device\n");
+
+ // Would read state here
+
+ generic_reset_device(dev);
+
+ for (i=0;i<state->num_port_ranges;i++) {
+ GENERIC_DEBUG_PRINT("generic: hooking ports 0x%x to 0x%x\n",state->port_ranges[i][0],state->port_ranges[i][1]);
+#if PORT_HOOKS
+ for (j=state->port_ranges[i][0]; j<=state->port_ranges[i][1];j++) {
+ if (dev_hook_io(dev, j, &generic_read_port, &generic_write_port)) {
+ GENERIC_DEBUG_PRINT("generic: can't hook port 0x%x (already hooked?)\n",j);
+ }
+ }
+#else
+ GENERIC_DEBUG_PRINT("generic: hooking ports not supported\n");
+#endif
+
+ }
+
+ for (i=0;i<state->num_address_ranges;i++) {
+ GENERIC_DEBUG_PRINT("generic: hooking addresses 0x%x to 0x%x\n",state->address_ranges[i][0],state->address_ranges[i][1]);
+#if MEM_HOOKS
+ if (dev_hook_mem(dev, state->address_ranges[i][0],state->address_ranges[i][1])) {
+ GENERIC_DEBUG_PRINT("generic: Can't hook addresses 0x%x to 0x%x (already hooked?)\n",
+ state->address_ranges[i][0],state->address_ranges[i][1]);
+ }
+#else
+ GENERIC_DEBUG_PRINT("generic: hooking addresses not supported\n");
+#endif
+
+ }
+
+ for (i=0;i<state->num_irq_ranges;i++) {
+ GENERIC_DEBUG_PRINT("generic: hooking irqs 0x%x to 0x%x\n",state->irq_ranges[i][0],state->irq_ranges[i][1]);
+#if IRQ_HOOKS
+ for (j=state->irq_ranges[i][0]; j<=state->irq_ranges[i][1];j++) {
+ if (dev_hook_irq(dev, j, &generic_interrupt)) {
+ GENERIC_DEBUG_PRINT("generic: can't hook irq 0x%x (already hooked?)\n",j);
+ }
+ }
+#else
+ GENERIC_DEBUG_PRINT("generic: hooking irqs not supported\n");
+#endif
+ }
+
+ return 0;
+}
+
+int generic_deinit_device(struct vm_device *dev)
+{
+ struct generic_internal *state = (struct generic_internal *) dev->private_data;
+ uint_t i,j;
+
+ GENERIC_DEBUG_PRINT("generic: deinit_device\n");
+
+ for (i=0;i<state->num_irq_ranges;i++) {
+ GENERIC_DEBUG_PRINT("generic: unhooking irqs 0x%x to 0x%x\n",state->irq_ranges[i][0],state->irq_ranges[i][1]);
+#if IRQ_HOOKS
+ for (j=state->irq_ranges[i][0]; j<=state->irq_ranges[i][1];j++) {
+ if (dev_unhook_irq(dev, j)) {
+ GENERIC_DEBUG_PRINT("generic: can't unhook irq 0x%x (already unhooked?)\n",j);
+ }
+ }
+#else
+ GENERIC_DEBUG_PRINT("generic: unhooking irqs not supported\n");
+#endif
+
+ }
+
+ for (i=0;i<state->num_address_ranges;i++) {
+ GENERIC_DEBUG_PRINT("generic: unhooking addresses 0x%x to 0x%x\n",state->address_ranges[i][0],state->address_ranges[i][1]);
+#if MEM_HOOKS
+ if (dev_unhook_mem(dev, state->address_ranges[i][0],state->address_ranges[i][1])) {
+ GENERIC_DEBUG_PRINT("generic: Can't unhook addresses 0x%x to 0x%x (already unhooked?)\n",
+ state->address_ranges[i][0],state->address_ranges[i][1]);
+ }
+#else
+ GENERIC_DEBUG_PRINT("generic: unhooking addresses not supported\n");
+#endif
+ }
+
+ for (i=0;i<state->num_port_ranges;i++) {
+ GENERIC_DEBUG_PRINT("generic: unhooking ports 0x%x to 0x%x\n",state->port_ranges[i][0],state->port_ranges[i][1]);
+#if PORT_HOOKS
+ for (j=state->port_ranges[i][0]; j<=state->port_ranges[i][1];j++) {
+ if (dev_unhook_io(dev, j)) {
+ GENERIC_DEBUG_PRINT("generic: can't unhook port 0x%x (already unhooked?)\n",j);
+ }
+ }
+#else
+ GENERIC_DEBUG_PRINT("generic: unhooking ports not supported\n");
+#endif
+
+ }
+
+ generic_reset_device(dev);
+ return 0;
+}
+
+
+
+
+
+static struct vm_device_ops dev_ops = {
+ .init = generic_init_device,
+ .deinit = generic_deinit_device,
+ .reset = generic_reset_device,
+ .start = generic_start_device,
+ .stop = generic_stop_device,
+};
+
+
+
+
+struct vm_device *create_generic(generic_port_range_type port_ranges[],
+ uint_t num_port_ranges,
+ generic_address_range_type address_ranges[],
+ uint_t num_address_ranges,
+ generic_irq_range_type irq_ranges[],
+ uint_t num_irq_ranges)
+{
+ struct generic_internal * generic_state = os_hooks->malloc(sizeof(struct generic_internal));
+
+
+ generic_state->num_port_ranges=num_port_ranges;
+ if (num_port_ranges>0) {
+ generic_state->port_ranges = os_hooks->malloc(sizeof(generic_address_range_type)*num_port_ranges);
+ memcpy(generic_state->port_ranges,port_ranges,sizeof(generic_port_range_type)*num_port_ranges);
+ } else {
+ generic_state->port_ranges=NULL;
+ }
+
+ generic_state->num_address_ranges=num_address_ranges;
+ if (num_address_ranges>0) {
+ generic_state->address_ranges = os_hooks->malloc(sizeof(generic_address_range_type)*num_address_ranges);
+ memcpy(generic_state->address_ranges,address_ranges,sizeof(generic_address_range_type)*num_address_ranges);
+ } else {
+ generic_state->address_ranges=NULL;
+ }
+ generic_state->num_irq_ranges=num_irq_ranges;
+ if (num_irq_ranges>0) {
+ generic_state->irq_ranges = os_hooks->malloc(sizeof(generic_address_range_type)*num_irq_ranges);
+ memcpy(generic_state->irq_ranges,irq_ranges,sizeof(generic_irq_range_type)*num_port_ranges);
+ } else {
+ generic_state->irq_ranges=NULL;
+ }
+
+
+ struct vm_device *device = create_device("GENERIC", &dev_ops, generic_state);
+
+ return device;
+}
#include <palacios/vmm.h>
#include <palacios/vmm_types.h>
+#define KEYBOARD_DEBUG 1
+
+#if KEYBOARD_DEBUG
+#define KEYBOARD_DEBUG_PRINT(first, rest...) do { SerialPrint(first, ## rest ); } while (0)
+#else
+#define KEYBOARD_DEBUG_PRINT(first, rest...)
+#endif
+
+
extern struct vmm_os_hooks *os_hooks;
extern void SerialPrint(const char *format, ...);
+// The currently targetted keyboard
+static struct vm_device *thekeyboard=NULL;
+
+
struct keyboard_internal {
- int x;
- // figure this out later - it should be the internal state of the keyboard buffer and
- // the emulated status, etc.
- // which should be fed from the underlying OS and drained via this interface
+ // read* is what is seen when reads are done from the VM
+ uchar_t read_status;
+ uchar_t read_scancode;
+ // write* is where we put the writes from the VM
+ uchar_t write_status;
+ uchar_t write_scancode;
+
+ uchar_t status_byte; // for on-board uC
+
+ uchar_t input_queue; // input queue is for communication *to* the on-board uC
+ uint_t input_queue_len; // num items queued
+ uchar_t output_queue; // output queue is for communcation *from* the on-board uC
+ uint_t output_queue_len; // num items queued
};
+static struct vm_device *demultiplex_injected_key(uchar_t status, uchar_t scancode)
+{
+ // this currently does nothing
+ return thekeyboard;
+}
+int keyboard_interrupt(uint_t irq,struct vm_device * dev);
-int keyboard_reset_device(struct vm_device * dev)
+void deliver_key_to_vmm(uchar_t status, uchar_t scancode)
{
- // struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
+ struct vm_device *dev = demultiplex_injected_key(status,scancode);
+
+ struct keyboard_internal *state = (struct keyboard_internal *)dev->private_data;
+
+ KEYBOARD_DEBUG_PRINT("keyboard: injected status 0x%x, and scancode 0x%x\n", status,scancode);
- SerialPrint("keyboard: reset device\n");
+ // This is wrong - the read status should be some combination of the
+ // status/scancode within the VM, and that of the actual device
+ state->read_status=status;
+ state->read_scancode=scancode;
+
+ keyboard_interrupt(KEYBOARD_IRQ,dev);
+
+}
+int keyboard_reset_device(struct vm_device * dev)
+{
+ struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
+
+ memset(data,0,sizeof(struct keyboard_internal));
+
+ KEYBOARD_DEBUG_PRINT("keyboard: reset device\n");
return 0;
int keyboard_start_device(struct vm_device *dev)
{
- SerialPrint("keyboard: start device\n");
+ KEYBOARD_DEBUG_PRINT("keyboard: start device\n");
return 0;
}
int keyboard_stop_device(struct vm_device *dev)
{
- SerialPrint("keyboard: stop device\n");
+ KEYBOARD_DEBUG_PRINT("keyboard: stop device\n");
return 0;
}
uint_t length,
struct vm_device * dev)
{
- //struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
+ struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
if (length==1) {
uchar_t data = *((uchar_t*)src);
- PrintDebug("keyboard: write of 0x%x to control port\n",data);
- Out_Byte(KEYBOARD_CONTROL_REG,data);
+ KEYBOARD_DEBUG_PRINT("keyboard: write of 0x%x to control port\n",data);
+ state->write_status=data;
return 1;
} else {
- PrintDebug("keyboard: unknown size write to control port!\n");
+ KEYBOARD_DEBUG_PRINT("keyboard: unknown size write to control port!\n");
return -1;
}
}
uint_t length,
struct vm_device * dev)
{
- //struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
+ struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
if (length==1) {
uchar_t data;
- PrintDebug("keyboard: read from control port: ");
- data=In_Byte(KEYBOARD_CONTROL_REG);
- PrintDebug("0x%x\n",data);
- memcpy(dest,&data,1);
+ KEYBOARD_DEBUG_PRINT("keyboard: read from control port: ");
+ data=state->read_status;
+ KEYBOARD_DEBUG_PRINT("0x%x\n",data);
+ memcpy(dest,&data,length);
return 1;
} else {
- PrintDebug("keyboard: unknown size read from control port!\n");
+ KEYBOARD_DEBUG_PRINT("keyboard: unknown size read from control port!\n");
return -1;
}
}
uint_t length,
struct vm_device * dev)
{
- //struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
+ struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
if (length==1) {
uchar_t data = *((uchar_t*)src);
- PrintDebug("keyboard: write of 0x%x to data port\n",data);
- Out_Byte(KEYBOARD_DATA_REG,data);
+ KEYBOARD_DEBUG_PRINT("keyboard: write of 0x%x to data port\n",data);
+ state->write_scancode=data;
return 1;
} else {
- PrintDebug("keyboard: unknown size write to data port!\n");
+ KEYBOARD_DEBUG_PRINT("keyboard: unknown size write to data port!\n");
return -1;
}
}
uint_t length,
struct vm_device * dev)
{
- //struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
+ struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
if (length==1) {
uchar_t data;
- PrintDebug("keyboard: read from data port: ");
- data=In_Byte(KEYBOARD_DATA_REG);
- PrintDebug("0x%x\n",data);
+ KEYBOARD_DEBUG_PRINT("keyboard: read from data port: ");
+ data=state->read_scancode;
+ KEYBOARD_DEBUG_PRINT("0x%x\n",data);
memcpy(dest,&data,1);
return 1;
} else {
- PrintDebug("keyboard: unknown size read from data port!\n");
+ KEYBOARD_DEBUG_PRINT("keyboard: unknown size read from data port!\n");
return -1;
}
}
int keyboard_interrupt(uint_t irq,
struct vm_device * dev)
{
- PrintDebug("keyboard: interrupt\n");
+ KEYBOARD_DEBUG_PRINT("keyboard: interrupt\n");
+
+ dev->vm->vm_ops.raise_irq(dev->vm,irq,0);
+
return 0;
- // Inject ?
+
}
// struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
- SerialPrint("keyboard: init_device\n");
+ KEYBOARD_DEBUG_PRINT("keyboard: init_device\n");
// Would read state here
dev_hook_io(dev, KEYBOARD_DATA_REG, &keyboard_read_data_port, &keyboard_write_data_port);
dev_hook_io(dev, KEYBOARD_CONTROL_REG, &keyboard_read_control_port, &keyboard_write_control_port);
- // hook irq
- // currently assume this is done in vm.c?
- //dev_hook_irq(dev,KEYBOARD_IRQ,&keyboard_interrupt);
-
+ //
+ // We do not hook the IRQ here. Instead, the underlying device driver
+ // is responsible to call us back
+ //
return 0;
}
int keyboard_deinit_device(struct vm_device *dev)
{
-
- //dev_unhook_irq(dev,KEYBOARD_IRQ);
dev_unhook_io(dev, KEYBOARD_DATA_REG);
dev_unhook_io(dev, KEYBOARD_CONTROL_REG);
struct vm_device *create_keyboard() {
+
+ if (thekeyboard!=NULL) {
+ KEYBOARD_DEBUG_PRINT("keyboard: creating >1 keyboard device. This will probably fail!\n");
+ }
+
struct keyboard_internal * keyboard_state = os_hooks->malloc(sizeof(struct keyboard_internal));
struct vm_device *device = create_device("KEYBOARD", &dev_ops, keyboard_state);
+ thekeyboard=device;
+
return device;
}
/*
* Keyboard driver
* Copyright (c) 2001,2004 David H. Hovemeyer <daveho@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/io.h>
#include <geekos/keyboard.h>
+
+static enum {TARGET_GEEKOS,TARGET_VMM} target=TARGET_GEEKOS;
+
+extern void deliver_key_to_vmm(uchar_t status, uchar_t scancode);
+
/* ----------------------------------------------------------------------
* Private data and functions
* ---------------------------------------------------------------------- */
*/
static void Keyboard_Interrupt_Handler(struct Interrupt_State* state)
{
+ uchar_t raw_status, raw_scancode;
+
uchar_t status, scanCode;
unsigned flag = 0;
bool release = false, shift;
Keycode keycode;
+ bool flagchange;
Begin_IRQ(state);
- // Print("Keybaord\n");
+ Print("Keyboard\n");
status = In_Byte(KB_CMD);
+
+ raw_status=status;
+
IO_Delay();
if ((status & KB_OUTPUT_FULL) != 0) {
- /* There is a byte available */
- scanCode = In_Byte(KB_DATA);
- IO_Delay();
-/*
- * Print("code=%x%s\n", scanCode, (scanCode&0x80) ? " [release]" : "");
- */
-
- if (scanCode & KB_KEY_RELEASE) {
- release = true;
- scanCode &= ~(KB_KEY_RELEASE);
- }
-
- if (scanCode >= SCAN_TABLE_SIZE) {
- Print("Unknown scan code: %x\n", scanCode);
+ /* There is a byte available */
+ scanCode = In_Byte(KB_DATA);
+ raw_scancode=scanCode;
+ Print("Keyboard: status=0x%x, scancode=0x%x\n", raw_status, raw_scancode);
+ IO_Delay();
+ /*
+ * Print("code=%x%s\n", scanCode, (scanCode&0x80) ? " [release]" : "");
+ */
+
+ if (scanCode & KB_KEY_RELEASE) {
+ release = true;
+ scanCode &= ~(KB_KEY_RELEASE);
+ }
+
+ if (scanCode >= SCAN_TABLE_SIZE) {
+ Print("Unknown scan code: %x\n", scanCode);
+ goto done;
+ }
+
+ /* Process the key */
+ shift = ((s_shiftState & SHIFT_MASK) != 0);
+ keycode = shift ? s_scanTableWithShift[scanCode] : s_scanTableNoShift[scanCode];
+
+ flagchange=false;
+
+ /* Update shift, control and alt state */
+ switch (keycode) {
+ case KEY_LSHIFT:
+ flag = LEFT_SHIFT;
+ break;
+ case KEY_RSHIFT:
+ flag = RIGHT_SHIFT;
+ break;
+ case KEY_LCTRL:
+ flag = LEFT_CTRL;
+ break;
+ case KEY_RCTRL:
+ flag = RIGHT_CTRL;
+ break;
+ case KEY_LALT:
+ flag = LEFT_ALT;
+ break;
+ case KEY_RALT:
+ flag = RIGHT_ALT;
+ break;
+ default:
+ goto noflagchange;
+ }
+
+ if (release)
+ s_shiftState &= ~(flag);
+ else
+ s_shiftState |= flag;
+
+ /*
+ * Shift, control and alt keys don't have to be
+ * queued, flags will be set!
+ */
+ // huh?
+ flagchange=true;
+ goto skip_flagchange;
+
+noflagchange:
+ /* Format the new keycode */
+ if (shift)
+ keycode |= KEY_SHIFT_FLAG;
+ if ((s_shiftState & CTRL_MASK) != 0)
+ keycode |= KEY_CTRL_FLAG;
+ if ((s_shiftState & ALT_MASK) != 0)
+ keycode |= KEY_ALT_FLAG;
+ if (release)
+ keycode |= KEY_RELEASE_FLAG;
+
+
+skip_flagchange:
+
+ if (target==TARGET_GEEKOS) {
+ if (raw_scancode==0xc4) { // F10 release
+ Print("Switching keyboard to VMM\n");
+ target=TARGET_VMM;
+ } else {
+ if (flagchange) {
goto done;
+ }
+ /* Put the keycode in the buffer */
+ Enqueue_Keycode(keycode);
+
+ /* Wake up event consumers */
+ Wake_Up(&s_waitQueue);
+
+ /*
+ * Pick a new thread upon return from interrupt
+ * (hopefully the one waiting for the keyboard event)
+ */
+ g_needReschedule = true;
}
-
- /* Process the key */
- shift = ((s_shiftState & SHIFT_MASK) != 0);
- keycode = shift ? s_scanTableWithShift[scanCode] : s_scanTableNoShift[scanCode];
-
- /* Update shift, control and alt state */
- switch (keycode) {
- case KEY_LSHIFT:
- flag = LEFT_SHIFT;
- break;
- case KEY_RSHIFT:
- flag = RIGHT_SHIFT;
- break;
- case KEY_LCTRL:
- flag = LEFT_CTRL;
- break;
- case KEY_RCTRL:
- flag = RIGHT_CTRL;
- break;
- case KEY_LALT:
- flag = LEFT_ALT;
- break;
- case KEY_RALT:
- flag = RIGHT_ALT;
- break;
- default:
- goto noflagchange;
+ } else if (target==TARGET_VMM) {
+ if (raw_scancode==0xc4) { // F10 release
+ Print("Switching keyboard to GeekOS\n");
+ target=TARGET_GEEKOS;
+ } else {
+ deliver_key_to_vmm(raw_status,raw_scancode);
}
-
- if (release)
- s_shiftState &= ~(flag);
- else
- s_shiftState |= flag;
-
- /*
- * Shift, control and alt keys don't have to be
- * queued, flags will be set!
- */
- goto done;
-
-noflagchange:
- /* Format the new keycode */
- if (shift)
- keycode |= KEY_SHIFT_FLAG;
- if ((s_shiftState & CTRL_MASK) != 0)
- keycode |= KEY_CTRL_FLAG;
- if ((s_shiftState & ALT_MASK) != 0)
- keycode |= KEY_ALT_FLAG;
- if (release)
- keycode |= KEY_RELEASE_FLAG;
-
- /* Put the keycode in the buffer */
- Enqueue_Keycode(keycode);
-
- /* Wake up event consumers */
- Wake_Up(&s_waitQueue);
-
- /*
- * Pick a new thread upon return from interrupt
- * (hopefully the one waiting for the keyboard event)
- */
- g_needReschedule = true;
+ }
}
-done:
+ done:
End_IRQ(state);
+
}
/* ----------------------------------------------------------------------
#include <geekos/vm.h>
#include <geekos/screen.h>
+#include <devices/generic.h>
#include <devices/nvram.h>
#include <devices/timer.h>
#include <devices/simple_pic.h>
hook_io_port(&(vm_info.io_map), 0x403, &IO_Read, &IO_Write_to_Serial, NULL);
{
+
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 * pit = create_pit();
+ //generic_port_range_type range = {0,1024} ; // hook first 1024 ports if not already hooked
+
+ //struct vm_device * generic = create_generic(&range,1,NULL,0,NULL,0);
+
+
attach_device(&(vm_info), nvram);
//attach_device(&(vm_info), timer);
attach_device(&(vm_info), pic);
attach_device(&(vm_info), pit);
//attach_device(&(vm_info), keyboard);
+ // Important that this be attached last!
+ //attach_device(&(vm_info), generic);
+
PrintDebugDevMgr(&(vm_info.dev_mgr));
}