--- /dev/null
+src/devices/ramdisk.c
+include/devices/ramdisk.h
+include/devices/ide.h
+
+Taken from BOCHS
+LPGL
+
+=====================================================================
+include/palacios/vmm_list.h
+
+Taken From Linux
+GPL...
+
+
+=====================================================================
+src/palacios/vmm_symbol.asm
+src/palacios/vmm_string.c
+include/palacios/vmm_string.h
+
+Taken from GeekOS
+/*
+ * Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
+ * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+=====================================================================
+
+src/palacios/vmm_hashtable.c
+include/palacios/vmm_hashtable.h
+
+hash table implementation based on work by Christopher Clark:
+
+Copyright (c) 2002, 2004, Christopher Clark
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the original author; nor the names of any contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+++ /dev/null
-TODO: decide on license, fill me in
--- /dev/null
+The Palacios Virtual Machine Monitor is developed by the V3VEE Project
+with funding from the United States National Science Foundation and
+the Department of Energy.
+
+The V3VEE Project is a joint project between Northwestern University
+and the University of New Mexico. You can find out more at
+http://www.v3vee.org
+
+Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+Copyright (c) 2008, Lei Xia <andrewlxia@northwestern.edu>
+Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the V3VEE Project, nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+IN THE FOLLOWING, "THE AUTHORS" REFERS TO THE COPYRIGHT HOLDERS AND
+ALL CONTRIBUTORS.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND THE V3VEE
+PROJECT ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+THE AUTHORS OR THE V3VEE PROJECT BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
--- /dev/null
+#!/bin/sh
+
+make DEBUG_ALL=1 world
+cp vmm.img iso
+mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o test.iso iso
+
--- /dev/null
+# Makefile for GeekOS kernel, userspace, and tools
+#
+# Northwestern University
+# (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+# (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+# (c) 2008, Lei Xia <xiaxlei@gmail.com>
+# (c) 2008, The V3VEE Project <http://www.v3vee.org>
+#
+# Based on GeekOS Makefile:
+# Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
+# $Revision: 1.71 $
+
+
+# This is free software. You are permitted to use,
+# redistribute, and modify it as specified in the file "COPYING".
+
+# Required software to build GeekOS:
+# - GNU Make (http://www.gnu.org/software/make)
+# - gcc 2.95.2 generating code for target (i386/ELF) and host platforms
+# - nasm (http://nasm.sourceforge.net)
+# - Perl5, AWK (any version), egrep
+#
+# Cygwin (http://cygwin.com) may be used to build GeekOS.
+# Make sure that gcc, binutils, nasm, and perl are installed.
+
+# NOTES:
+# - This makefile has been written carefully to work correctly
+# with the -j (parallel make) option. I regularly use "make -j 2"
+# to speed the build process on 2 processor systems.
+
+
+
+
+# ----------------------------------------------------------------------
+# Configuration -
+# Various options specifying how GeekOS should be built,
+# what source files to build, which user programs to build,
+# etc. This is generally the only section of the makefile
+# that will need to be modified.
+# ----------------------------------------------------------------------
+PROJECT_ROOT := ..
+PALACIOS_BUILD_DIR := $(PROJECT_ROOT)/palacios/build
+GEEKOS_BUILD_DIR := $(PROJECT_ROOT)/geekos/build
+GUEST_ISO_DIR := /opt/vmm-tools/isos
+
+# List of targets to build by default.
+# These targets encompass everything needed to boot
+# and run GeekOS.
+ALL_TARGETS := palacios geekos
+
+QEMU := /usr/local/qemu/bin/qemu-system-x86_64
+
+
+
+#when -DNDEBUG is set the kassert functions are disabled
+#JRLDEBUG=-DNDEBUG
+
+# DEBUG=1 means VMM_DEBUG, VMM_INFO, and VMM_TRACE are enabled
+# as are SERIAL_PRINT_DEBUG
+#
+DEBUG_SECTIONS := DEBUG=1
+
+ifeq ($(DEBUG_ALL),1)
+ DEBUG_SECTIONS:= $(DEBUG_SECTIONS) DEBUG_ALL=1
+endif
+
+ifeq ($(DEBUG_SHADOW_PAGING),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_SHADOW_PAGING=1
+else
+ifeq ($(DEBUG_SHADOW_PAGING),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_SHADOW_PAGING=0
+endif
+endif
+
+ifeq ($(DEBUG_CTRL_REGS),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_CTRL_REGS=1
+else
+ifeq ($(DEBUG_CTRL_REGS),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_CTRL_REGS=0
+endif
+endif
+
+ifeq ($(DEBUG_INTERRUPTS),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_INTERRUPTS=1
+else
+ifeq ($(DEBUG_INTERRUPTS),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_INTERRUPTS=0
+endif
+endif
+
+ifeq ($(DEBUG_IO),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_IO=1
+else
+ifeq ($(DEBUG_IO),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_IO=0
+endif
+endif
+
+ifeq ($(DEBUG_KEYBOARD),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_KEYBOARD=1
+else
+ifeq ($(DEBUG_KEYBOARD),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_KEYBOARD=0
+endif
+endif
+
+ifeq ($(DEBUG_PIC),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_PIC=1
+else
+ifeq ($(DEBUG_PIC),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_PIC=0
+endif
+endif
+
+ifeq ($(DEBUG_PIT),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_PIT=1
+else
+ifeq ($(DEBUG_PIT),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_PIT=0
+endif
+endif
+
+ifeq ($(DEBUG_NVRAM),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_NVRAM=1
+else
+ifeq ($(DEBUG_NVRAM),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_NVRAM=0
+endif
+endif
+
+ifeq ($(DEBUG_GENERIC),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_GENERIC=1
+else
+ifeq ($(DEBUG_GENERIC),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_GENERIC=0
+endif
+endif
+
+ifeq ($(DEBUG_EMULATOR),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_EMULATOR=1
+else
+ifeq ($(DEBUG_EMULATOR),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_EMULATOR=0
+endif
+endif
+
+ifeq ($(DEBUG_RAMDISK),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_RAMDISK=1
+else
+ifeq ($(DEBUG_RAMDISK),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_RAMDISK=0
+endif
+endif
+
+
+# ----------------------------------------------------------------------
+# Targets -
+# Specifies files to be built
+# ----------------------------------------------------------------------
+
+# Default target - see definition of ALL_TARGETS in Configuration section
+all : $(ALL_TARGETS)
+
+
+
+palacios:
+ (cd $(PALACIOS_BUILD_DIR) && make $(DEBUG_SECTIONS) world)
+
+
+geekos:
+ cp $(PALACIOS_BUILD_DIR)/libv3vee.a $(GEEKOS_BUILD_DIR)/palacios/
+ cp $(PALACIOS_BUILD_DIR)/../lib/xed/libxed.a $(GEEKOS_BUILD_DIR)/palacios/
+ cp $(PALACIOS_BUILD_DIR)/vm_kernel $(GEEKOS_BUILD_DIR)/palacios/
+ (cd $(GEEKOS_BUILD_DIR) && make clean && make)
+
+
+
+
+# make ready to boot over PXE
+geekos-pxe: geekos
+ cp $(GEEKOS_BUILD_DIR)/vmm.img /tftpboot/vmm.img
+
+geekos-run: geekos
+ $(QEMU) -m 1024 -serial file:serial.out -cdrom $(GUEST_ISO_DIR)/puppy.iso -fda $(GEEKOS_BUILD_DIR)/vmm.img
+
+geekos-iso: geekos
+ cp $(GEEKOS_BUILD_DIR)/vmm.img iso/vmm.img
+ mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o test.iso iso
+
+
+
+force:
+
+
+
+
+# Clean build directories of generated files
+clean :
+ for d in $(GEEKOS_BUILD_DIR) $(PALACIOS_BUILD_DIR); do \
+ (cd $$d && make clean); \
+ done
+
+
--- /dev/null
+# Makefile for GeekOS kernel, userspace, and tools
+#
+# Northwestern University
+# (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+# (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+# (c) 2008, Lei Xia <xiaxlei@gmail.com>
+# (c) 2008, The V3VEE Project <http://www.v3vee.org>
+#
+# Based on GeekOS Makefile:
+# Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
+# $Revision: 1.71 $
+
+
+# This is free software. You are permitted to use,
+# redistribute, and modify it as specified in the file "COPYING".
+
+# Required software to build GeekOS:
+# - GNU Make (http://www.gnu.org/software/make)
+# - gcc 2.95.2 generating code for target (i386/ELF) and host platforms
+# - nasm (http://nasm.sourceforge.net)
+# - Perl5, AWK (any version), egrep
+#
+# Cygwin (http://cygwin.com) may be used to build GeekOS.
+# Make sure that gcc, binutils, nasm, and perl are installed.
+
+# NOTES:
+# - This makefile has been written carefully to work correctly
+# with the -j (parallel make) option. I regularly use "make -j 2"
+# to speed the build process on 2 processor systems.
+
+
+# Base address of kernel
+#
+# Note: at top of memory minus three pages (GDT/TSS/IDT)
+# minus maximum size
+#
+#
+# Note that the code will initially load at 0x10000
+#
+# The setup code needs to copy it up to this address and jump there
+#
+KERNEL_BASE_ADDR := 0x00100000
+
+# Kernel entry point function
+KERNEL_ENTRY = $(SYM_PFX)Main
+
+
+PROJECT_ROOT := ..
+VPATH := $(PROJECT_ROOT)/src
+
+#when -DNDEBUG is set the kassert functions are disabled
+#JRLDEBUG=-DNDEBUG
+
+# DEBUG=1 means VMM_DEBUG, VMM_INFO, and VMM_TRACE are enabled
+# as are SERIAL_PRINT_DEBUG
+#
+DEBUG=1
+DEBUG_SECTIONS=
+
+ifeq ($(DEBUG_ALL),1)
+ DEBUG_SECTIONS:= $(DEBUG_SECTIONS) -DDEBUG_SHADOW_PAGING -DDEBUG_CTRL_REGS -DDEBUG_INTERRUPTS -DDEBUG_IO -DDEBUG_KEYBOARD -DDEBUG_PIC -DDEBUG_PIT -DDEBUG_NVRAM -DDEBUG_EMULATOR -DDEBUG_GENERIC -DDEBUG_RAMDISK
+endif
+
+ifeq ($(DEBUG_SHADOW_PAGING),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_SHADOW_PAGING
+else
+ifeq ($(DEBUG_SHADOW_PAGING),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -UDEBUG_SHADOW_PAGING
+endif
+endif
+
+ifeq ($(DEBUG_CTRL_REGS),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_CTRL_REGS
+else
+ifeq ($(DEBUG_CTRL_REGS),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -UDEBUG_CTRL_REGS
+endif
+endif
+
+ifeq ($(DEBUG_INTERRUPTS),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_INTERRUPTS
+else
+ifeq ($(DEBUG_DEBUG_INTERRUPTS),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -UDEBUG_INTERRUPTS
+endif
+endif
+
+ifeq ($(DEBUG_IO),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_IO
+else
+ifeq ($(DEBUG_IO),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -UDEBUG_IO
+endif
+endif
+
+ifeq ($(DEBUG_KEYBOARD),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_KEYBOARD
+else
+ifeq ($(DEBUG_KEYBOARD),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -UDEBUG_KEYBOARD
+endif
+endif
+
+ifeq ($(DEBUG_PIC),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_PIC
+else
+ifeq ($(DEBUG_PIC),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -UDEBUG_PIC
+endif
+endif
+
+ifeq ($(DEBUG_PIT),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_PIT
+else
+ifeq ($(DEBUG_PIT),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -UDEBUG_PIT
+endif
+endif
+
+ifeq ($(DEBUG_NVRAM),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_NVRAM
+else
+ifeq ($(DEBUG_NVRAM),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -UDEBUG_NVRAM
+endif
+endif
+
+ifeq ($(DEBUG_GENERIC),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_GENERIC
+else
+ifeq ($(DEBUG_GENERIC),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -UDEBUG_GENERIC
+endif
+endif
+
+ifeq ($(DEBUG_EMULATOR),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_EMULATOR
+else
+ifeq ($(DEBUG_EMULATOR),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -UDEBUG_EMULATOR
+endif
+endif
+
+ifeq ($(DEBUG_RAMDISK),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_RAMDISK
+else
+ifeq ($(DEBUG_RAMDISK),0)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -UDEBUG_RAMDISK
+endif
+endif
+
+
+#DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DTEST_NE2K
+
+ifeq ($(DEBUG),1)
+ JRLDEBUG= -DSERIAL_PRINT_DEBUG=1 -DSERIAL_PRINT_DEBUG_LEVEL=10 -DSERIAL_PRINT=1 -DVMM_DEBUG=1 -DVMM_INFO=1 -DVMM_TRACE=1 $(DEBUG_SECTIONS)
+
+else
+ JRLDEBUG= -DSERIAL_PRINT_DEBUG=0 -DSERIAL_PRINT_DEBUG_LEVEL=999999 -DSERIAL_PRINT=0 -DVMM_DEBUG=0 -DVMM_INFO=0 -DVMM_TRACE=0
+endif
+
+
+#
+# DECODER is the decoder that will be used
+# currently we only support xed
+#
+DECODER=XED
+
+DECODER_FLAGS=
+DECODER_SRCS=
+DECODER_LIBS=
+
+ifeq ($(DECODER),XED)
+DECODER_SRCS := vmm_xed.c
+DECODER_FLAGS := -L../lib/xed
+DECODER_LIBS := -lxed
+else
+# This is an error
+endif
+
+#
+#TCPSTACK, uIP is used currently
+#
+TCPSTACK=UIP
+
+
+
+
+#
+# This is wrong for current cygwin - no changes needed
+#
+# Figure out if we're compiling with cygwin, http://cygwin.com
+#
+#
+#SYSTEM_NAME := $(shell uname -s)
+#ifeq ($(findstring CYGWIN,$(SYSTEM_NAME)),CYGWIN)
+#SYM_PFX := _
+#EXTRA_C_OPTS := -DNEED_UNDERSCORE -DGNU_WIN32
+#EXTRA_NASM_OPTS := -DNEED_UNDERSCORE
+#NON_ELF_SYSTEM := yes
+#EXTRA_CC_USER_OPTS := -Dmain=geekos_main
+#endif
+
+
+
+
+# ----------------------------------------------------------------------
+# Configuration -
+# Various options specifying how GeekOS should be built,
+# what source files to build, which user programs to build,
+# etc. This is generally the only section of the makefile
+# that will need to be modified.
+# ----------------------------------------------------------------------
+
+# List of targets to build by default.
+# These targets encompass everything needed to boot
+# and run GeekOS.
+ALL_TARGETS := vmm.img vm_kernel
+
+
+# Kernel source files
+KERNEL_C_SRCS := idt.c int.c trap.c irq.c io.c \
+ blockdev.c ide.c ne2k.c \
+ keyboard.c screen.c timer.c \
+ mem.c crc32.c \
+ gdt.c tss.c segment.c \
+ bget.c malloc.c \
+ synch.c kthread.c \
+ serial.c reboot.c \
+ paging.c \
+ debug.c vmm_stubs.c vm.c pci.c\
+ queue.c socket.c net.c ring_buffer.c \
+ main.c
+
+
+# Kernel object files built from C source files
+KERNEL_C_OBJS := $(KERNEL_C_SRCS:%.c=geekos/%.o)
+
+# Kernel assembly files
+KERNEL_ASM_SRCS := lowlevel.asm
+
+KERNEL_GAS_SRCS := testvm.s udivdi3.s
+
+# Kernel object files build from assembler source files
+KERNEL_ASM_OBJS := $(KERNEL_ASM_SRCS:%.asm=geekos/%.o)
+
+KERNEL_GAS_OBJS := $(KERNEL_GAS_SRCS:%.s=geekos/%.o)
+
+
+# All kernel object files
+KERNEL_OBJS := $(KERNEL_C_OBJS) \
+ $(KERNEL_ASM_OBJS) $(KERNEL_GAS_OBJS)
+
+# Common library source files.
+# This library is linked into both the kernel and user programs.
+# It provides string functions and generic printf()-style
+# formatted output.
+COMMON_C_SRCS := fmtout.c string.c memmove.c
+
+# Common library object files.
+COMMON_C_OBJS := $(COMMON_C_SRCS:%.c=common/%.o)
+
+VMM_ASM_SRCS := svm_lowlevel.asm \
+# vmx_lowlevel.asm
+
+VMM_ASM_OBJS := $(VMM_ASM_SRCS:%.asm=palacios/%.o)
+
+
+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_time.c \
+ vmm_shadow_paging.c vm_guest_mem.c \
+ vm_dev.c vmm_dev_mgr.c vmm_decoder.c \
+ svm_halt.c svm_pause.c svm_wbinvd.c \
+ vmm_config.c vmm_hashtable.c \
+ vmm_string.c vmm_emulator.c vmm_queue.c\
+ $(DECODER_SRCS)
+# vmx.c vmcs_gen.c vmcs.c
+
+VMM_C_OBJS := $(VMM_C_SRCS:%.c=palacios/%.o)
+
+VMM_OBJS := $(VMM_C_OBJS) $(VMM_ASM_OBJS)
+
+
+
+
+DEVICE_C_SRCS := generic.c keyboard.c nvram.c timer.c simple_pic.c 8259a.c 8254.c serial.c ramdisk.c cdrom.c
+
+DEVICE_C_OBJS := $(DEVICE_C_SRCS:%.c=devices/%.o)
+
+DEVICE_OBJS := $(DEVICE_C_OBJS)
+
+V3LIBS := $(DECODER_LIBS)
+
+
+TCPSTACK_C_SRCS := psock.c timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-neighbor.c uip-split.c resolv.c
+
+TCPSTACK_C_OBJS := $(TCPSTACK_C_SRCS:%.c=net/%.o)
+
+TCPSTACK_OBJS := $(TCPSTACK_C_OBJS)
+
+
+
+
+# ----------------------------------------------------------------------
+# Tools -
+# This section defines programs that are used to build GeekOS.
+# ----------------------------------------------------------------------
+
+# Uncomment if cross compiling
+TARGET_CC_PREFIX := $(PROJECT_ROOT)/../devtools/i386/bin/i386-elf-
+#TARGET_CC_PREFIX := i386-elf-
+
+# Target C compiler. gcc 2.95.2 or later should work.
+TARGET_CC := $(TARGET_CC_PREFIX)gcc
+#TARGET_CC := $(TARGET_CC_PREFIX)gcc34 -m32
+
+# Host C compiler. This is used to compile programs to execute on
+# the host platform, not the target (x86) platform. On x86/ELF
+# systems, such as Linux and FreeBSD, it can generally be the same
+# as the target C compiler.
+HOST_CC := gcc
+
+# Target linker. GNU ld is probably to only one that will work.
+TARGET_LD := $(TARGET_CC_PREFIX)ld -melf_i386
+
+# Target archiver
+TARGET_AR := $(TARGET_CC_PREFIX)ar
+
+# Target ranlib
+TARGET_RANLIB := $(TARGET_CC_PREFIX)ranlib
+
+# Target nm
+TARGET_NM := $(TARGET_CC_PREFIX)nm
+
+# Target objcopy
+TARGET_OBJCOPY := $(TARGET_CC_PREFIX)objcopy
+
+# Nasm (http://nasm.sourceforge.net)
+NASM := $(PROJECT_ROOT)/../devtools/bin/nasm
+#NASM := /opt/vmm-tools/bin/nasm
+
+AS = as --32
+
+# Tool to build PFAT filesystem images.
+BUILDFAT := tools/builtFat.exe
+
+# Perl5 or later
+PERL := perl
+
+# Pad a file so its size is a multiple of some unit (i.e., sector size)
+PAD := $(PERL) $(PROJECT_ROOT)/scripts/pad
+
+# Create a file filled with zeroes.
+ZEROFILE := $(PERL) $(PROJECT_ROOT)/scripts/zerofile
+
+# Calculate size of file in sectors
+NUMSECS := $(PERL) $(PROJECT_ROOT)/scripts/numsecs
+
+
+FD_SECTORS_PER_TRACK := $(PERL) $(PROJECT_ROOT)/scripts/numsecs_per_track
+
+
+# ----------------------------------------------------------------------
+# Definitions -
+# Options passed to the tools.
+# ----------------------------------------------------------------------
+
+# Flags used for all C source files
+GENERAL_OPTS := -O -Wall $(EXTRA_C_OPTS) $(VMM_FLAGS) $(BOOT_FLAGS) -fPIC
+CC_GENERAL_OPTS := $(GENERAL_OPTS) -Werror
+
+# Flags used for kernel C source files
+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__ -D__V3_32BIT__ $(DECODER_FLAGS) $(JRLDEBUG)
+
+# Flags used for VMM C ASM files
+NASM_VMM_OPTS := -I$(PROJECT_ROOT)/src/palacios/ -f elf $(EXTRA_NASM_OPTS)
+
+# Flags user for kernel assembly files
+NASM_KERNEL_OPTS := -I$(PROJECT_ROOT)/src/geekos/ -f elf $(EXTRA_NASM_OPTS)
+
+# Flags used for common library and libc source files
+CC_USER_OPTS := -I$(PROJECT_ROOT)/include -I$(PROJECT_ROOT)/include/libc \
+ $(EXTRA_CC_USER_OPTS)
+
+# Flags passed to objcopy program (strip unnecessary sections from kernel.exe)
+OBJCOPY_FLAGS := -R .dynamic -R .note -R .comment
+
+# ----------------------------------------------------------------------
+# Rules -
+# Describes how to compile the source files.
+# ----------------------------------------------------------------------
+
+# Compilation of kernel C source files
+
+geekos/%.o : geekos/%.c
+ $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) $< -o geekos/$*.o
+
+
+# Compilation of kernel assembly source files
+geekos/%.o : geekos/%.asm
+ $(NASM) $(NASM_KERNEL_OPTS) $< -o geekos/$*.o
+
+# Compilation of test VM
+geekos/%.o : geekos/%.s
+ $(AS) $< -o geekos/$*.o
+
+geekos/%.o : geekos/%.S
+ $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) $< -o geekos/$*.o
+
+# Compilation of common library C source files
+common/%.o : common/%.c
+ $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_USER_OPTS) $< -o common/$*.o
+
+palacios/%.o : palacios/%.c
+ $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_VMM_OPTS) $< -o palacios/$*.o
+
+palacios/%.o : palacios/%.asm
+ $(NASM) $(NASM_VMM_OPTS) $< -o palacios/$*.o
+
+devices/%.o : devices/%.c
+ $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_VMM_OPTS) $< -o devices/$*.o
+
+devices/%.o : devices/%.asm
+ $(NASM) $(NASM_VMM_OPTS) $< -o devices/$*.o
+
+net/%.o : net/%.c
+ $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_USER_OPTS) $< -o net/$*.o
+
+# ----------------------------------------------------------------------
+# Targets -
+# Specifies files to be built
+# ----------------------------------------------------------------------
+
+# Default target - see definition of ALL_TARGETS in Configuration section
+all : $(ALL_TARGETS)
+
+
+#geekos/vmx_lowlevel.o: $(PROJECT_ROOT)/src/geekos/vmx_lowlevel.asm
+# $(NASM) -O99 \
+# -f elf \
+# -I$(PROJECT_ROOT)/src/geekos/ \
+# $(PROJECT_ROOT)/src/geekos/vmx_lowlevel.asm \
+# -o $@
+
+
+#geekos/test: geekos/test.o geekos/vmcs.o geekos/vmx_lowlevel.o
+# $(CC) geekos/test.o geekos/vmcs.o geekos/vmx_lowlevel.o -o geekos/test
+
+# Standard floppy image - just boots the kernel
+fd.img : geekos/fd_boot.bin geekos/setup.bin geekos/kernel.bin
+ cat geekos/fd_boot.bin geekos/setup.bin geekos/kernel.bin > _temp
+ $(PAD) _temp 512
+ cp _temp fd.img
+
+vmm.img : fd.img
+ cp fd.img vmm.img
+ $(PAD) vmm.img 1474560
+
+rombios_link:
+ ln -s -f ../src/vmboot/rombios/BIOS-bochs-latest rombios
+
+vgabios_link:
+ ln -s -f ../src/vmboot/vgabios/VGABIOS-lgpl-latest.bin vgabios
+
+force_rombios: rombios_link
+ (cd ../src/vmboot/rombios; make clean; make)
+
+force_vgabios: vgabios_link
+ (cd ../src/vmboot/vgabios; make clean; make)
+
+force_payload: force_rombios force_vgabios
+ ../scripts/make_payload.pl payload_layout.txt vm_kernel
+
+inter1: force_payload
+ -make clean
+
+world: inter1 vmm.img
+
+# make ready to boot over PXE
+pxe: vmm.img
+ cp vmm.img /tftpboot/vmm.img
+
+run: vmm.img
+ /usr/local/qemu/bin/qemu-system-x86_64 -m 1024 -serial file:serial.out -cdrom puppy.iso -fda vmm.img
+
+iso: vmm.img
+ cp vmm.img iso/vmm.img
+ mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o test.iso iso
+
+
+
+# Floppy boot sector (first stage boot loader).
+geekos/fd_boot.bin : geekos/setup.bin geekos/kernel.bin $(PROJECT_ROOT)/src/geekos/fd_boot.asm
+ $(NASM) -f bin \
+ -I$(PROJECT_ROOT)/src/geekos/ \
+ -DNUM_SETUP_SECTORS=`$(NUMSECS) geekos/setup.bin` \
+ -DNUM_KERN_SECTORS=`$(NUMSECS) geekos/kernel.bin` \
+ -DSECTORS_PER_TRACK=`$(FD_SECTORS_PER_TRACK) geekos/kernel.bin geekos/setup.bin` \
+ $(PROJECT_ROOT)/src/geekos/fd_boot.asm \
+ -o $@
+
+# Setup program (second stage boot loader).
+geekos/setup.bin : geekos/kernel.bin $(PROJECT_ROOT)/src/geekos/setup.asm
+ $(NASM) -f bin \
+ -I$(PROJECT_ROOT)/src/geekos/ \
+ -DENTRY_POINT=0x`egrep 'Main$$' geekos/kernel.syms |awk '{print $$1}'` \
+ -DVMM_SIZE=`$(NUMSECS) geekos/kernel.bin` \
+ $(PROJECT_ROOT)/src/geekos/setup.asm \
+ -o $@
+ $(PAD) $@ 2048
+
+# Loadable (flat) kernel image.
+geekos/kernel.bin : geekos/kernel.exe
+ $(TARGET_OBJCOPY) $(OBJCOPY_FLAGS) -S -O binary geekos/kernel.exe geekos/kernel.bin
+ $(PAD) $@ 512
+
+# The kernel executable and symbol map.
+geekos/kernel.exe : $(KERNEL_OBJS) $(COMMON_C_OBJS) $(VMM_OBJS) $(DEVICE_OBJS) $(TCPSTACK_OBJS) vm_kernel
+ $(TARGET_LD) -o geekos/kernel.exe -Ttext $(KERNEL_BASE_ADDR) -e $(KERNEL_ENTRY) \
+ $(DECODER_FLAGS) \
+ $(KERNEL_OBJS) $(COMMON_C_OBJS) $(VMM_OBJS) $(DEVICE_OBJS) $(V3LIBS) $(TCPSTACK_OBJS) -b binary vm_kernel
+ $(TARGET_NM) geekos/kernel.exe > geekos/kernel.syms
+
+
+force:
+
+
+#vm_kernel: force
+# $(PAD) vm_kernel 512
+# @echo "VM kernel lives at 0x100000 and is" `$(NUMSECS) vm_kernel` "sectors long"
+
+
+
+
+# Clean build directories of generated files
+clean :
+ for d in geekos common libc user tools palacios devices net; do \
+ (cd $$d && rm -f *); \
+ done
+
+
+# Build header file dependencies, so source files are recompiled when
+# header files they depend on are modified.
+depend : $(GENERATED_LIBC_SRCS)
+ $(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) \
+ $(KERNEL_C_SRCS:%.c=$(PROJECT_ROOT)/src/geekos/%.c) \
+ | $(PERL) -n -e 's,^(\S),geekos/$$1,;print' \
+ > depend.mak
+ $(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_USER_OPTS) \
+ $(COMMON_C_SRCS:%.c=$(PROJECT_ROOT)/src/common/%.c) \
+ | $(PERL) -n -e 's,^(\S),common/$$1,;print' \
+ >> depend.mak
+ $(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) \
+ $(VMM_C_SRCS:%.c=$(PROJECT_ROOT)/src/palacios/%.c) \
+ | $(PERL) -n -e 's,^(\S),palacios/$$1,;print' \
+ >> depend.mak
+ $(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) \
+ $(DEVICE_C_SRCS:%.c=$(PROJECT_ROOT)/src/devices/%.c) \
+ | $(PERL) -n -e 's,^(\S),devices/$$1,;print' \
+ >> depend.mak
+
+# By default, there are no header file dependencies.
+depend.mak :
+ touch $@
+
+include depend.mak
/usr/local/qemu/bin/qemu-system-x86_64 -serial file:serial.out -m 1024 -fda vmm.img -cdrom guest_no_timer.iso
+
+
+
+Creating a grub based bootable cd ISO image:
+
+mkidr iso
+mkdir -p iso/boot/grub
+
+get "menu.lst" and "stage2_eltorito" from the grub files located in vmm-tools/others
+copy menu.lst and stage2_eltorito into iso/boot/grub
+
+mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o test.iso iso
--- /dev/null
+#!/bin/sh
+
+/usr/local/qemu/bin/qemu-system-x86_64 -serial file:serial.out -m 1024 -fda vmm.img -cdrom /opt/vmm-tools/isos/puppy.iso
--- /dev/null
+#!/bin/sh
+
+/usr/local/qemu/bin/qemu-system-x86_64 -serial file:serial.out -m 1024 -fda vmm.img -cdrom /opt/vmm-tools/isos/winxp.iso
--- /dev/null
+default=0
+timeout=0
+title V3VEE
+color light-green/brown blink-red/blue
+foreground bbbbbb
+background 000000
+root (cd)
+kernel /vmm.img
+initrd /puppy.iso
--- /dev/null
+# Makefile for GeekOS kernel, userspace, and tools
+#
+# Northwestern University
+# (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+# (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+# (c) 2008, Lei Xia <xiaxlei@gmail.com>
+# (c) 2008, The V3VEE Project <http://www.v3vee.org>
+#
+# Based on GeekOS Makefile:
+# Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
+# $Revision: 1.71 $
+
+
+# This is free software. You are permitted to use,
+# redistribute, and modify it as specified in the file "COPYING".
+
+# Required software to build GeekOS:
+# - GNU Make (http://www.gnu.org/software/make)
+# - gcc 2.95.2 generating code for target (i386/ELF) and host platforms
+# - nasm (http://nasm.sourceforge.net)
+# - Perl5, AWK (any version), egrep
+#
+# Cygwin (http://cygwin.com) may be used to build GeekOS.
+# Make sure that gcc, binutils, nasm, and perl are installed.
+
+# NOTES:
+# - This makefile has been written carefully to work correctly
+# with the -j (parallel make) option. I regularly use "make -j 2"
+# to speed the build process on 2 processor systems.
+
+
+# Base address of kernel
+#
+# Note: at top of memory minus three pages (GDT/TSS/IDT)
+# minus maximum size
+#
+#
+# Note that the code will initially load at 0x10000
+#
+# The setup code needs to copy it up to this address and jump there
+#
+KERNEL_BASE_ADDR := 0x00100000
+
+# Kernel entry point function
+KERNEL_ENTRY = $(SYM_PFX)Main
+
+
+PROJECT_ROOT := ..
+V3_ROOT := $(PROJECT_ROOT)/../palacios
+VPATH := $(PROJECT_ROOT)/src
+
+
+
+#
+#TCPSTACK, uIP is used currently
+#
+TCPSTACK=UIP
+
+#
+#TCPSTACK, uIP is used currently
+#
+UIP=OFF
+
+#
+#LWIP, ON -- used, OFF -- not used
+#
+LWIP=ON
+
+
+#
+# This is wrong for current cygwin - no changes needed
+#
+# Figure out if we're compiling with cygwin, http://cygwin.com
+#
+#
+#SYSTEM_NAME := $(shell uname -s)
+#ifeq ($(findstring CYGWIN,$(SYSTEM_NAME)),CYGWIN)
+#SYM_PFX := _
+#EXTRA_C_OPTS := -DNEED_UNDERSCORE -DGNU_WIN32
+#EXTRA_NASM_OPTS := -DNEED_UNDERSCORE
+#NON_ELF_SYSTEM := yes
+#EXTRA_CC_USER_OPTS := -Dmain=geekos_main
+#endif
+
+
+
+
+# ----------------------------------------------------------------------
+# Configuration -
+# Various options specifying how GeekOS should be built,
+# what source files to build, which user programs to build,
+# etc. This is generally the only section of the makefile
+# that will need to be modified.
+# ----------------------------------------------------------------------
+
+# List of targets to build by default.
+# These targets encompass everything needed to boot
+# and run GeekOS.
+ALL_TARGETS := vmm.img
+
+
+# Kernel source files
+KERNEL_C_SRCS := idt.c int.c trap.c irq.c io.c \
+ blockdev.c ide.c ne2k.c \
+ keyboard.c screen.c timer.c \
+ mem.c crc32.c \
+ gdt.c tss.c segment.c \
+ bget.c malloc.c \
+ synch.c kthread.c \
+ serial.c reboot.c \
+ paging.c \
+ debug.c vmm_stubs.c vm.c pci.c\
+ queue.c socket.c net.c ring_buffer.c \
+ main.c
+
+
+# Kernel object files built from C source files
+KERNEL_C_OBJS := $(KERNEL_C_SRCS:%.c=geekos/%.o)
+
+# Kernel assembly files
+KERNEL_ASM_SRCS := lowlevel.asm
+
+KERNEL_GAS_SRCS :=
+
+# Kernel object files build from assembler source files
+KERNEL_ASM_OBJS := $(KERNEL_ASM_SRCS:%.asm=geekos/%.o)
+
+KERNEL_GAS_OBJS := $(KERNEL_GAS_SRCS:%.s=geekos/%.o)
+
+
+# All kernel object files
+KERNEL_OBJS := $(KERNEL_C_OBJS) \
+ $(KERNEL_ASM_OBJS) $(KERNEL_GAS_OBJS)
+
+# Common library source files.
+# This library is linked into both the kernel and user programs.
+# It provides string functions and generic printf()-style
+# formatted output.
+COMMON_C_SRCS := fmtout.c string.c memmove.c
+
+# Common library object files.
+COMMON_C_OBJS := $(COMMON_C_SRCS:%.c=common/%.o)
+
+
+
+
+V3_LD_FLAGS := -L./palacios/
+#V3_LIBS := -lxed -lv3vee
+V3_LIBS := ./palacios/libxed.a ./palacios/libv3vee.a ./palacios/libxed.a ./palacios/libv3vee.a
+
+
+
+
+
+
+ifeq ($(UIP),ON)
+ UIP_C_SRCS := psock.c timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-neighbor.c uip-split.c resolv.c
+ UIP_C_OBJS := $(UIP_C_SRCS:%.c=net/%.o)
+else
+ UIP_C_SRCS :=
+ UIP_C_OBJS :=
+endif
+
+ifeq ($(LWIP),ON)
+ LWIP_OBJS := lwip/*.o
+ CC_LWIP_OPTS := -I$(PROJECT_ROOT)/include/lwip -I$(PROJECT_ROOT)/include/lwip/ipv4 -I$(PROJECT_ROOT)/include/libc -DLWIP_DEBUG
+else
+ LWIP_OBJS :=
+ CC_LWIP_OPTS :=
+endif
+
+TCPSTACK_OBJS := $(UIP_C_OBJS) $(LWIP_OBJS)
+
+
+# ----------------------------------------------------------------------
+# Tools -
+# This section defines programs that are used to build GeekOS.
+# ----------------------------------------------------------------------
+
+# Uncomment if cross compiling
+TARGET_CC_PREFIX := $(PROJECT_ROOT)/../devtools/i386/bin/i386-elf-
+#TARGET_CC_PREFIX := i386-elf-
+
+# Target C compiler. gcc 2.95.2 or later should work.
+TARGET_CC := $(TARGET_CC_PREFIX)gcc
+#TARGET_CC := $(TARGET_CC_PREFIX)gcc34 -m32
+
+# Host C compiler. This is used to compile programs to execute on
+# the host platform, not the target (x86) platform. On x86/ELF
+# systems, such as Linux and FreeBSD, it can generally be the same
+# as the target C compiler.
+HOST_CC := gcc
+
+# Target linker. GNU ld is probably to only one that will work.
+TARGET_LD := $(TARGET_CC_PREFIX)ld -melf_i386
+
+# Target archiver
+TARGET_AR := $(TARGET_CC_PREFIX)ar
+
+# Target ranlib
+TARGET_RANLIB := $(TARGET_CC_PREFIX)ranlib
+
+# Target nm
+TARGET_NM := $(TARGET_CC_PREFIX)nm
+
+# Target objcopy
+TARGET_OBJCOPY := $(TARGET_CC_PREFIX)objcopy
+
+# Nasm (http://nasm.sourceforge.net)
+NASM := $(PROJECT_ROOT)/../devtools/bin/nasm
+#NASM := /opt/vmm-tools/bin/nasm
+
+AS = as --32
+
+# Tool to build PFAT filesystem images.
+BUILDFAT := tools/builtFat.exe
+
+# Perl5 or later
+PERL := perl
+
+# Pad a file so its size is a multiple of some unit (i.e., sector size)
+PAD := $(PERL) $(PROJECT_ROOT)/scripts/pad
+
+# Create a file filled with zeroes.
+ZEROFILE := $(PERL) $(PROJECT_ROOT)/scripts/zerofile
+
+# Calculate size of file in sectors
+NUMSECS := $(PERL) $(PROJECT_ROOT)/scripts/numsecs
+
+
+FD_SECTORS_PER_TRACK := $(PERL) $(PROJECT_ROOT)/scripts/numsecs_per_track
+
+
+# ----------------------------------------------------------------------
+# Definitions -
+# Options passed to the tools.
+# ----------------------------------------------------------------------
+
+# Flags used for all C source files
+GENERAL_OPTS := -O -Wall $(EXTRA_C_OPTS) $(BOOT_FLAGS) -fPIC
+CC_GENERAL_OPTS := $(GENERAL_OPTS) -Werror
+
+# Flags used for kernel C source files
+CC_KERNEL_OPTS := -g -DGEEKOS -I$(PROJECT_ROOT)/include -I$(V3_ROOT)/include
+
+
+# Flags user for kernel assembly files
+NASM_KERNEL_OPTS := -I$(PROJECT_ROOT)/src/geekos/ -f elf $(EXTRA_NASM_OPTS)
+
+# Flags used for common library and libc source files
+CC_USER_OPTS := -I$(PROJECT_ROOT)/include -I$(PROJECT_ROOT)/include/libc \
+ $(EXTRA_CC_USER_OPTS) -I$(V3_ROOT)/include
+
+# Flags passed to objcopy program (strip unnecessary sections from kernel.exe)
+OBJCOPY_FLAGS := -R .dynamic -R .note -R .comment
+
+# ----------------------------------------------------------------------
+# Rules -
+# Describes how to compile the source files.
+# ----------------------------------------------------------------------
+
+# Compilation of kernel C source files
+
+geekos/%.o : geekos/%.c
+ $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) $(CC_LWIP_OPTS) $< -o geekos/$*.o
+
+
+# Compilation of kernel assembly source files
+geekos/%.o : geekos/%.asm
+ $(NASM) $(NASM_KERNEL_OPTS) $< -o geekos/$*.o
+
+
+# Compilation of common library C source files
+common/%.o : common/%.c
+ $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_USER_OPTS) $< -o common/$*.o
+
+
+net/%.o : net/%.c
+ $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_USER_OPTS) $< -o net/$*.o
+
+# ----------------------------------------------------------------------
+# Targets -
+# Specifies files to be built
+# ----------------------------------------------------------------------
+
+# Default target - see definition of ALL_TARGETS in Configuration section
+all : $(ALL_TARGETS)
+
+
+#geekos/vmx_lowlevel.o: $(PROJECT_ROOT)/src/geekos/vmx_lowlevel.asm
+# $(NASM) -O99 \
+# -f elf \
+# -I$(PROJECT_ROOT)/src/geekos/ \
+# $(PROJECT_ROOT)/src/geekos/vmx_lowlevel.asm \
+# -o $@
+
+
+#geekos/test: geekos/test.o geekos/vmcs.o geekos/vmx_lowlevel.o
+# $(CC) geekos/test.o geekos/vmcs.o geekos/vmx_lowlevel.o -o geekos/test
+
+# Standard floppy image - just boots the kernel
+fd.img : geekos/fd_boot.bin geekos/setup.bin geekos/kernel.bin
+ cat geekos/fd_boot.bin geekos/setup.bin geekos/kernel.bin > _temp
+ $(PAD) _temp 512
+ cp _temp fd.img
+
+
+vmm.img: fd.img
+ cp fd.img vmm.img
+ $(PAD) vmm.img 1474560
+
+
+
+
+
+
+# Floppy boot sector (first stage boot loader).
+geekos/fd_boot.bin : geekos/setup.bin geekos/kernel.bin $(PROJECT_ROOT)/src/geekos/fd_boot.asm
+ $(NASM) -f bin \
+ -I$(PROJECT_ROOT)/src/geekos/ \
+ -DNUM_SETUP_SECTORS=`$(NUMSECS) geekos/setup.bin` \
+ -DNUM_KERN_SECTORS=`$(NUMSECS) geekos/kernel.bin` \
+ -DSECTORS_PER_TRACK=`$(FD_SECTORS_PER_TRACK) geekos/kernel.bin geekos/setup.bin` \
+ $(PROJECT_ROOT)/src/geekos/fd_boot.asm \
+ -o $@
+
+# Setup program (second stage boot loader).
+geekos/setup.bin : geekos/kernel.bin $(PROJECT_ROOT)/src/geekos/setup.asm
+ $(NASM) -f bin \
+ -I$(PROJECT_ROOT)/src/geekos/ \
+ -DENTRY_POINT=0x`egrep 'Main$$' geekos/kernel.syms |awk '{print $$1}'` \
+ -DVMM_SIZE=`$(NUMSECS) geekos/kernel.bin` \
+ $(PROJECT_ROOT)/src/geekos/setup.asm \
+ -o $@
+ $(PAD) $@ 2048
+
+# Loadable (flat) kernel image.
+geekos/kernel.bin : geekos/kernel.exe
+ $(TARGET_OBJCOPY) $(OBJCOPY_FLAGS) -S -O binary geekos/kernel.exe geekos/kernel.bin
+ $(PAD) $@ 512
+
+# The kernel executable and symbol map.
+geekos/kernel.exe : $(KERNEL_OBJS) $(COMMON_C_OBJS) $(TCPSTACK_OBJS)
+ $(TARGET_LD) -o geekos/kernel.exe -Ttext $(KERNEL_BASE_ADDR) -e $(KERNEL_ENTRY) \
+ $(V3_LD_FLAGS) \
+ $(KERNEL_OBJS) $(COMMON_C_OBJS) $(TCPSTACK_OBJS) $(V3_LIBS) -b binary ./palacios/vm_kernel
+ $(TARGET_NM) geekos/kernel.exe > geekos/kernel.syms
+
+
+force:
+
+
+#vm_kernel: force
+# $(PAD) vm_kernel 512
+# @echo "VM kernel lives at 0x100000 and is" `$(NUMSECS) vm_kernel` "sectors long"
+
+
+
+
+# Clean build directories of generated files
+clean :
+ for d in geekos common libc user tools net; do \
+ (cd $$d && rm -f *); \
+ done
+
+
+# Build header file dependencies, so source files are recompiled when
+# header files they depend on are modified.
+depend : $(GENERATED_LIBC_SRCS)
+ $(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) \
+ $(KERNEL_C_SRCS:%.c=$(PROJECT_ROOT)/src/geekos/%.c) \
+ | $(PERL) -n -e 's,^(\S),geekos/$$1,;print' \
+ > depend.mak
+ $(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_USER_OPTS) \
+ $(COMMON_C_SRCS:%.c=$(PROJECT_ROOT)/src/common/%.c) \
+ | $(PERL) -n -e 's,^(\S),common/$$1,;print' \
+ >> depend.mak
+
+
+# By default, there are no header file dependencies.
+depend.mak :
+ touch $@
+
+include depend.mak
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+#ifndef __DEBUG_H
+#define __DEBUG_H
+
+#include <geekos/serial.h>
+#include <geekos/screen.h>
+
+
+
+
+void PrintBoth(const char * format, ...);
+
+
+
+#endif
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Matt Wojcik
+ * Copyright (c) 2008, Peter Kamm
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Matt Wojcik
+ * Author: Peter Kamm
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#ifndef GEEKOS_NE2K_H
#define GEEKOS_NE2K_H
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef __NET_H__
+#define __NET_H__
+
+
+
+void Init_Network();
+
+
+void test_network();
+
+
+
+
+
+#endif
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef GEEKOS_PCI_H
+#define GEEKOS_PCI_H
+
+#include <geekos/ktypes.h>
+
+int Init_PCI();
+
+#endif /* GEEKOS_PCI_H */
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef __QUEUE_H__
+#define __QUEUE_H__
+
+#include <geekos/list2.h>
+#include <geekos/ktypes.h>
+#include <geekos/malloc.h>
+
+
+/* IMPORTANT:
+ * This implementation currently does no locking, and as such is not
+ * SMP/thread/interrupt safe
+ */
+
+
+struct queue_entry {
+ void * entry;
+ struct list_head entry_list;
+};
+
+
+struct gen_queue {
+ uint_t num_entries;
+ struct list_head entries;
+
+ // We really need to implement this....
+ // void * lock;
+};
+
+
+struct gen_queue * create_queue();
+void init_queue(struct gen_queue * queue);
+
+void enqueue(struct gen_queue * queue, void * entry);
+void * dequeue(struct gen_queue * queue);
+
+
+
+
+#endif
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef __RING_BUFFER_H__
+#define __RING_BUFFER_H__
+
+
+#include <geekos/ktypes.h>
+
+
+struct ring_buffer {
+ uchar_t * buf;
+ uint_t size;
+
+ uint_t start;
+ uint_t end;
+ uint_t current_len;
+
+};
+
+
+void init_ring_buffer(struct ring_buffer * ring, uint_t size);
+struct ring_buffer * create_ring_buffer(uint_t size);
+
+void free_ring_buffer(struct ring_buffer * ring);
+
+
+int rb_read(struct ring_buffer * ring, char * dst, uint_t len);
+int rb_peek(struct ring_buffer * ring, char * dst, uint_t len);
+int rb_delete(struct ring_buffer * ring, uint_t len);
+int rb_write(struct ring_buffer * ring, char * src, uint_t len);
+int rb_data_len(struct ring_buffer * ring);
+int rb_capacity(struct ring_buffer * ring);
+
+
+void print_ring_buffer(struct ring_buffer * ring);
+
+
+#endif // ! __RING_BUFFER_H__
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Matt Wojcik
+ * Copyright (c) 2008, Peter Kamm
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Matt Wojcik
+ * Author: Peter Kamm
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#ifndef GEEKOS_RTL8139_H
#define GEEKOS_RTL8139_H
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef SERIAL_H
+#define SERIAL_H
+
+#include <geekos/irq.h>
+#include <geekos/string.h>
+#include <geekos/io.h>
+#include <geekos/screen.h>
+
+#define COM1_IRQ 4
+#define DEFAULT_SERIAL_ADDR 0x3F8
+
+
+#ifndef SERIAL_PRINT_DEBUG_LEVEL
+#define SERIAL_PRINT_DEBUG_LEVEL 10
+#endif
+
+void SerialPutChar(unsigned char c);
+
+void SerialPrint(const char * format, ...);
+void SerialPrintLevel(int level, const char * format, ...);
+void SerialPrintList(const char * format, va_list ap);
+
+void SerialPutLine(char * line);
+void SerialPutLineN(char * line, int len);
+
+
+void SerialPrintHex(unsigned char x);
+void SerialMemDump(unsigned char *start, int n);
+
+void Init_Serial();
+void InitSerialAddr(unsigned short io_addr);
+
+#endif
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef GEEKOS_SOCKET_H
+#define GEEKOS_SOCKET_H
+
+#include <geekos/ring_buffer.h>
+#include <uip/uip.h>
+#include <geekos/kthread.h>
+
+
+typedef enum {WAITING, CLOSED, LISTEN, ESTABLISHED} sock_state_t;
+
+struct socket {
+ int in_use;
+ struct Thread_Queue recv_wait_queue;
+ struct ring_buffer *send_buf;
+ struct ring_buffer *recv_buf;
+ struct uip_conn *con;
+
+ sock_state_t state;
+
+};
+
+
+void init_socket_layer();
+
+int connect(const uchar_t ip_addr[4], ushort_t port);
+int close(const int sockfd);
+int recv(int sockfd, void * buf, uint_t len);
+int send(int sockfd, void * buf, uint_t len);
+
+void set_ip_addr(uchar_t addr[4]);
+
+
+#endif
int Start_Timer_MSecs(int msecs, timerCallback cb, void * arg);
int Start_Timer(int ticks, timerCallback, void * arg);
+
double Get_Remaining_Timer_Secs(int id);
int Get_Remaining_Timer_MSecs(int id);
int Get_Remaining_Timer_Ticks(int id);
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef __VM_H
+#define __VM_H
+
+int RunVMM(struct Boot_Info * bootInfo);
+
+
+#endif
+
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VMM_STUBS_H
#define __VMM_STUBS_H
--- /dev/null
+#ifndef __PING_H__
+#define __PING_H__
+
+void ping_init(void);
+
+#endif /* __PING_H__ */
--- /dev/null
+/* ne2k network interface for lwip\r
+ *\r
+ * Lei Xia (lxia@northwestern.edu)\r
+ */
+
+#ifndef __NETIF_NE2KIF_H__
+#define __NETIF_NE2KIF_H__
+
+#include <lwip/lwip/netif.h>
+#include <lwip/lwip/err.h>
+#include <geekos/ktypes.h>
+#include <geekos/ne2k.h>
+
+extern struct netif ne2kif;
+
+err_t ne2kif_init(struct netif *netif);
+
+void ne2kif_input(struct NE2K_Packet_Info * info, uchar_t * pkt);
+
+err_t ne2kif_output(struct netif * netif, struct pbuf * p);
+
+#endif /*__NETIF_NE2KIF_H__*/
#ifndef __CLOCK_H__
#define __CLOCK_H__
-#include <palacios/vmm_types.h>
+#include <geekos/ktypes.h>
#include <geekos/timer.h>
#define CLOCK_CONF_SECOND 1000
--- /dev/null
+#! /usr/bin/perl
+
+# Find the function name from the value of the EIP (instruction pointer)
+# register from a Bochs crash report. Uses the kernel symbol
+# map (kernel.syms) produced by compiling the kernel.
+
+use strict qw(refs vars);
+use FileHandle;
+
+if (scalar(@ARGV) != 2){
+ print STDERR "Usage: eipToFunction kernel.syms <eip value>\n";
+ print STDERR " eip value should be in hex\n";
+ exit 1;
+}
+
+my $syms = shift @ARGV;
+my $eip = hex(shift @ARGV);
+
+my @text = ();
+
+my $fh = new FileHandle("<$syms");
+(defined $fh) || die "Couldn't open $syms: $!\n";
+while (<$fh>) {
+ #print $_;
+ if (/^([0-9A-Fa-f]+)\s+[Tt]\s+(\S+)\s*$/) {
+ push @text, [hex($1), $2];
+ }
+}
+$fh->close();
+#print scalar(@text),"\n";
+
+@text = sort { $a->[0] <=> $b->[0] } @text;
+
+my $last = undef;
+
+foreach my $entry (@text) {
+ last if ($eip < $entry->[0]);
+ $last = $entry;
+}
+printf("%s\n",(defined $last) ? $last->[1] : "not found");
+
+# vim:ts=4
--- /dev/null
+#! /usr/bin/perl
+
+# Find the address of a symbol in the storage map.
+
+use strict qw(refs vars);
+use FileHandle;
+
+if ( scalar(@ARGV) != 2 ) {
+ print "Usage: findaddr <storage map> <symbol name>\n";
+ exit 1;
+}
+
+my $storage = shift @ARGV;
+my $symbol = shift @ARGV;
+
+my $fh = new FileHandle("<$storage");
+(defined $fh) || die "Couldn't open storage map: $!\n";
+
+while ( <$fh> ) {
+ if ( /^\s*(0x([0-9]|[a-f]|[A-F])+)\s+\Q$symbol\E\s*$/ ) {
+ print $1, "\n";
+ last;
+ }
+}
+
+$fh->close();
--- /dev/null
+#!/usr/bin/perl
+
+$#ARGV==0 or die "gimme a filename\n";
+
+$file=shift;
+
+@list=();
+
+open(HEADER,">$file.h");
+open(SOURCE,">$file.c");
+
+print HEADER "#ifndef $file\n";
+print HEADER "#define $file\n";
+print HEADER "#include <geekos/vmcs.h>\n";
+
+print SOURCE "#include <geekos/$file.h>\n";
+
+while (<STDIN>) {
+ if (/\#define\s+(\S+)\s+/) {
+ push @list, $1;
+ GenSerUnserCode($1);
+ }
+}
+
+GenPrintAllCode(@list);
+
+print HEADER "#endif\n";
+
+sub GenSerUnserCode {
+ my $name=shift;
+
+ print SOURCE <<END
+
+void Set_$name(uint_t val) { VMCS_WRITE($name,val); }
+uint_t Get_$name() { uint_t rc; VMCS_READ($name,&rc); return rc; }
+
+void Print_$name() { PrintTrace("$name = %x\\n", Get_$name()); }
+
+END
+
+;
+ print HEADER <<END2
+
+void Set_$name(uint_t val);
+uint_t Get_$name();
+
+void Print_$name();
+
+END2
+
+;
+
+}
+
+
+sub GenPrintAllCode {
+ print SOURCE "void PrintTrace_VMCS_ALL() {\n";
+ while (my $name=shift) {
+ print SOURCE " PrintTrace_$name();\n";
+ }
+ print SOURCE "}\n";
+ print HEADER "void PrintTrace_VMCS_ALL();\n";
+}
--- /dev/null
+#! /usr/bin/perl
+
+# Script to process include/geekos/errno.h to produce a table
+# of error description strings that can be compiled and
+# linked into libc.
+
+use strict qw(refs vars);
+
+my @errs = ();
+my @syms = ();
+
+$errs[0] = 'No error';
+
+while (<>) {
+ if (m,^#define\s*(\S+)\s*(-\d+)\s*/\*\s*(.*\S)\s*\*/\s*$,) {
+ $errs[- $2] = $3;
+ $syms[- $2] = $1;
+ }
+}
+
+print "const char *__strerrTable[] = {\n";
+for (my $i = 0; $i < scalar(@errs); $i++) {
+ print " \"", $errs[$i], "\", /* ", $syms[$i], " */\n";
+}
+print "};\n";
+print "const int __strerrTableSize = sizeof(__strerrTable) / sizeof(const char *);\n";
+
+# vim:ts=4
--- /dev/null
+#!/usr/bin/perl
+
+$file = $ARGV[0];
+
+while(1) {
+ open (FILE,">>$file");
+ $foo = <STDIN>;
+ chomp $foo;
+ print FILE pack("C", hex("0x$foo"));
+ close FILE;
+}
+
--- /dev/null
+#! /usr/bin/perl
+
+# A script to analyze the output of "objdump -h" on the
+# kernel executable file.
+
+use strict qw(vars refs);
+use FileHandle;
+
+my $kernfile = shift @ARGV;
+(defined $kernfile) || die "usage: kernsize <kernfile>\n";
+
+my $kern_fh = new FileHandle("<$kernfile");
+(defined $kern_fh) || die "can't open $kernfile: $!\n";
+
+my $objdump_fh = new FileHandle("objdump -h $kernfile|");
+while ( <$objdump_fh> ) {
+ chop;
+ s/^\s+//;
+ my @fields = split(/\s+/, $_);
+ if ( $fields[0] =~ /^[0-9]$/ ) {
+# print "text start is ", $fields[5], "\n" if $fields[0] eq '0';
+ my $size = hex($fields[2]);
+ my $offset = hex($fields[5]);
+
+ print $fields[0], " (", $fields[1], "): size=$size, offset=$offset\n";
+
+ printf("Word at beginning of section is %08x\n", ReadWord($kern_fh,$offset) );
+ }
+}
+$objdump_fh->close();
+
+sub ReadWord {
+ my ($fh, $offset) = @_;
+ seek $fh, $offset, SEEK_SET;
+ my $buf = 'X' x 4;
+ read $fh, $buf, 4;
+ return unpack('V',$buf);
+}
--- /dev/null
+#!/usr/bin/perl
+
+$magic = 0xf1e2d3c4;
+
+use FileHandle;
+
+if (scalar(@ARGV) != 2) {
+ print STDERR "usage: make_payload.pl <cfg-file> <out-file>\n";
+ exit 1;
+}
+
+my $config_file = shift @ARGV;
+my $out_file = shift @ARGV;
+
+open (CFGFILE, "$config_file");
+@cfg = <CFGFILE>;
+close CFGFILE;
+
+my $num_regions = 0;
+
+my @region_names = ();
+my %region_map = {};
+
+foreach $line (@cfg) {
+ chomp $line;
+ ($file, $dst) = split(/:/, $line);
+ push @region_names, $file;
+ $region_map{$file} = hex($dst); #unpack('N', pack("h8",$dst));
+ print "" . hex($dst) . "\n";
+ $num_regions++;
+}
+
+
+
+my $fh = new FileHandle(">$out_file");
+binmode $fh;
+
+syswrite $fh, pack('L', $magic), 4;
+syswrite $fh, pack('L', $num_regions), 4;
+
+foreach $file (@region_names) {
+ my $size = (-s $file);
+
+ print "$file to " . $region_map{$file}. " ($size bytes)\n";
+ syswrite $fh, pack('L', $size), 4;
+ syswrite $fh, pack('L', $region_map{$file}), 4;
+}
+
+
+my $file;
+while (($file = shift @region_names)) {
+ my $in_fh = new FileHandle("<$file");
+ (defined $in_fh) || die "Couldn't open $file: $!\n";
+ binmode $in_fh;
+
+ my $buf = chr(0) x 1024;
+ my $n;
+ while (($n = sysread($in_fh, $buf, 1024)) > 0) {
+ syswrite($fh, $buf, $n);
+ }
+ $in_fh->close();
+}
+
+
+$fh->close();
--- /dev/null
+#! /usr/bin/perl
+
+# Build a binary image containing a pseudo fat filesystem with the listed files
+
+# $Revision: 1.1 $
+use FileHandle;
+
+if ( scalar(@ARGV) < 2 ) {
+ print STDERR "usage: mkuprog <diskImage> <filenames>\n";
+ exit 1;
+}
+
+
+$filename = shift @ARGV;
+$filecount = scalar ( @ARGV );
+
+$fh = new FileHandle(">$filename");
+
+write
+
+while (scalar(@ARGV)) {
+ $filename = shift @ARGV;
+
+ print "got file ", $filename, "\n";
+}
--- /dev/null
+#! /usr/bin/perl
+
+# From a binary image containing a user program, generate
+# C code initializing a User_Program struct.
+
+# $Revision: 1.1 $
+
+use strict qw(refs vars);
+use FileHandle;
+
+if ( scalar(@ARGV) != 3 ) {
+ print STDERR "usage: mkuprog <filename> <progname> <entry addr>\n";
+ exit 1;
+}
+
+my $filename = shift @ARGV;
+my $progname = shift @ARGV;
+my $entryAddr = shift @ARGV;
+
+my $fh = new FileHandle("<$filename");
+(defined $fh) || die "Couldn't open $filename: $!\n";
+binmode $fh;
+
+my $dataArrayName = $progname . "Data";
+my $structName = $progname . "Prog";
+print "const unsigned char $dataArrayName"."[] = {\n";
+
+my $LINEWIDTH = 10;
+
+my $buf = chr(0) x $LINEWIDTH;
+my $n;
+my $size = 0;
+while ( ($n = read( $fh, $buf, $LINEWIDTH )) > 0 ) {
+ $size += $n;
+ my $i;
+ print " ";
+ for ( $i = 0; $i < $n; $i++ ) {
+ my $c = ord( substr($buf, $i, 1) );
+ printf( "0x%x,", $c );
+ }
+ print "\n";
+}
+
+print "};\n";
+
+$fh->close();
+
+print << "END";
+const struct User_Program $structName = {
+ "$progname",
+ $size,
+ $entryAddr,
+ $dataArrayName
+};
+END
--- /dev/null
+#! /usr/bin/perl
+
+# Find the number of 512-byte sectors needed to store
+# given file.
+
+# $Revision: 1.1 $
+
+use strict qw(refs vars);
+
+if ( scalar(@ARGV) != 1 ) {
+ print STDERR "Usage: numsecs <filename>\n";
+ exit 1;
+}
+
+my $filename = shift @ARGV;
+my $size = (-s $filename );
+die "Couldn't get size of $filename: $!" if ( !defined $size );
+
+my $result = int($size / 512);
+my $remainder = $size % 512;
+$result++ if ( $remainder > 0 );
+
+print "$result\n";
--- /dev/null
+#! /usr/bin/perl
+
+# Find the number of 512-byte sectors needed to store
+# given file.
+
+# $Revision: 1.1 $
+
+use strict qw(refs vars);
+
+my $sectors = 0;
+my $filename = "";
+
+foreach $filename (@ARGV) {
+
+ my $size = (-s $filename );
+ die "Couldn't get size of $filename: $!" if ( !defined $size );
+
+ my $result = int($size / 512);
+ my $remainder = $size % 512;
+ $result++ if ( $remainder > 0 );
+
+ $sectors += $result;
+}
+
+if ($sectors <= 2879) {
+ print "18\n";
+} else {
+ print "36\n";
+}
+
--- /dev/null
+#! /usr/bin/perl
+
+# Pad a file with zero bytes to make its length
+# an even multiple of some value.
+
+# $Revision: 1.1 $
+
+use strict qw(refs vars);
+use FileHandle;
+
+if ( scalar(@ARGV) != 2 ) {
+ print STDERR "usage: pad <filename> <multiple>\n";
+ exit 1;
+}
+
+my $filename = shift @ARGV;
+my $multiple = shift @ARGV;
+
+my $size = (-s $filename);
+die "Couldn't get size of $filename: $!" if ( !defined $size );
+
+my $num_pad = ($multiple - ($size % $multiple)) % $multiple;
+
+my $buf = chr(0) x $num_pad;
+
+my $fh = new FileHandle(">>$filename");
+die "Couldn't open $filename: $!" if ( !defined $fh );
+binmode $fh;
+syswrite $fh, $buf, $num_pad, 0;
+$fh->close();
--- /dev/null
+#! /usr/bin/perl
+
+# A version of cat written in perl.
+
+use strict qw(refs vars);
+use FileHandle;
+
+binmode STDOUT;
+
+my $buf = chr(0) x 1024;
+
+my $file;
+while ( ($file = shift @ARGV) ) {
+ my $fh = new FileHandle("<$file");
+ (defined $fh) || die "Couldn't open $file: $!\n";
+ binmode $fh;
+
+ my $n;
+ while ( ($n = sysread($fh, $buf, 1024)) > 0 ) {
+ syswrite( STDOUT, $buf, $n );
+ }
+ $fh->close();
+}
--- /dev/null
+#! /usr/bin/perl
+
+# Inspect a 32 word at a specified offset in a file.
+# $Revision: 1.1 $
+
+use strict qw(refs vars);
+use FileHandle;
+
+my $filename = shift @ARGV;
+my $offset = shift @ARGV;
+
+((defined $filename) && (defined $offset))
+ || die "Usage: pw <filename> <offset>\n";
+
+my $fh = new FileHandle("<$filename");
+printf( "%08x\n", ReadWord($fh, $offset) );
+
+sub ReadWord {
+ my ($fh, $offset) = @_;
+ seek $fh, $offset, SEEK_SET;
+ my $buf = 'X' x 4;
+ read $fh, $buf, 4;
+ return unpack('V',$buf);
+}
--- /dev/null
+#! /usr/bin/perl
+
+# Scan a file for a 32-bit word with a particular value.
+# $Revision: 1.1 $
+
+use strict qw(refs vars);
+use FileHandle;
+
+my $filename = shift @ARGV;
+my $word_value = shift @ARGV;
+
+((defined $filename) && (defined $word_value))
+ || die "Usage: scan <filename> <word value in hex>\n";
+
+my $fh = new FileHandle("<$filename");
+my $val = hex($word_value);
+
+my $buf = ' ' x 4;
+
+my $offset = 0;
+while ( read( $fh, $buf, 4) == 4 ) {
+ my $out = unpack "V", $buf;
+ if ( $out == $val ) {
+ print "Found value $word_value at offset $offset\n";
+ exit;
+ }
+ $offset += 4;
+}
+print "Didn't find value $word_value\n";
--- /dev/null
+#!/usr/bin/perl
+
+
+$file = $ARGV[0];
+$ofile = $ARGV[1];
+
+open(INFILE, "$file");
+@lines = <INFILE>;
+close INFILE;
+
+open(OUTFILE, ">$ofile");
+
+
+print OUTFILE "\%ifndef VMCS_FIELDS_ASM\n\%define VMCS_FIELDS_ASM\n\n";
+
+foreach $line (@lines) {
+
+ if ($line =~ /\#define\s+(\S+)\s+(\S+)*/) {
+ print OUTFILE $1 . " equ " . $2 . "\n";
+ }
+
+}
+
+
+print OUTFILE "\n\%endif\n\n";
+
+close OUTFILE;
+
+
--- /dev/null
+#! /usr/bin/perl
+
+# This script is used for creating a file full of zeroes,
+# which we use to create the hard disk image used by bochs.
+
+use strict qw(refs vars);
+use FileHandle;
+use IO::Seekable;
+
+if ( scalar(@ARGV) != 2 ) {
+ print "Usage: zerofile <output file> <num sectors>\n";
+ exit 1;
+}
+
+my $outfile = shift @ARGV;
+my $numsecs = shift @ARGV;
+
+my $buf = chr(0) x 1;
+
+my $fh = new FileHandle(">$outfile");
+(defined $fh) || die "Couldn't open $outfile: $!\n";
+binmode $fh;
+
+if ( !sysseek( $fh, ($numsecs * 512) - 1, SEEK_SET ) ) {
+ die "Couldn't seek in $outfile: $!\n";
+}
+if ( !syswrite( $fh, $buf, 1 ) ) {
+ die "Couldn't write to $outfile: $!\n";
+}
+
+$fh->close();
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <geekos/debug.h>
+
+
+void PrintBoth(const char * format, ...) {
+ va_list args;
+
+ va_start(args, format);
+ PrintList(format, args);
+ SerialPrintList(format, args);
+ va_end(args);
+}
EXPORT Flush_TLB
; CPUID functions
-EXPORT cpuid_ecx
-EXPORT cpuid_eax
-EXPORT cpuid_edx
+;EXPORT cpuid_ecx
+;EXPORT cpuid_eax
+;EXPORT cpuid_edx
; Utility Functions
-EXPORT Set_MSR
-EXPORT Get_MSR
+;EXPORT Set_MSR
+;EXPORT Get_MSR
EXPORT Get_CR2
*/
struct Page* g_pageList;
-#ifdef RAMDISK_BOOT
ulong_t g_ramdiskImage;
ulong_t s_ramdiskSize;
-#endif
+
/*
* Number of pages currently available on the freelist.
ulong_t heapEnd;
ulong_t vmmMemEnd;
- /*Zheng 08/03/2008*/
-#ifdef RAMDISK_BOOT
+
g_ramdiskImage = bootInfo->ramdisk_image;
s_ramdiskSize = bootInfo->ramdisk_size;
ulong_t initrdAddr;
ulong_t initrdEnd;
-#endif
+
KASSERT(bootInfo->memSizeKB > 0);
/* ** */
vmmMemEnd = Round_Up_To_Page(pageListEnd + VMM_AVAIL_MEM_SIZE);
-#ifdef RAMDISK_BOOT
/*
* Zheng 08/03/2008
* copy the ramdisk to this area
memcpy((ulong_t *)initrdAddr, (ulong_t *)g_ramdiskImage, s_ramdiskSize);
PrintBoth(" done\n");
PrintBoth("mem.c(%d) Set 0 to unused bytes in the last ramdisk page from %x to %x", __LINE__, initrdAddr+s_ramdiskSize, initrdEnd);
- memset((ulong_t *)initrdAddr+s_ramdiskSize, 0, initrdEnd-(initrdAddr+s_ramdiskSize));
+ memset((ulong_t *)initrdAddr + s_ramdiskSize, 0, initrdEnd - (initrdAddr + s_ramdiskSize));
PrintBoth(" done\n");
- /*
- * Zheng 08/03/2008
- */
- vm_range_start = initrdEnd;
- vm_range_end = endOfMem;
-#else
+
+
/*
* the disgusting way to get at the memory assigned to a VM
*/
- vm_range_start = vmmMemEnd;
- vm_range_end = endOfMem;
-
-#endif
+ //vm_range_start = vmmMemEnd;
+ //vm_range_end = endOfMem;
+ /*
+ * Zheng 08/03/2008
+ */
+ vm_range_start = initrdEnd;
+ vm_range_end = endOfMem;
+
Add_Page_Range(0, PAGE_SIZE, PAGE_UNUSED); // BIOS area
Add_Page_Range(PAGE_SIZE, PAGE_SIZE * 3, PAGE_ALLOCATED); // Intial kernel thread obj + stack
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Matt Wojcik
+ * Copyright (c) 2008, Peter Kamm
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Matt Wojcik
+ * Author: Peter Kamm
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#include <geekos/ne2k.h>
#include <geekos/debug.h>
#include <geekos/io.h>
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <geekos/malloc.h>
#include <geekos/pci.h>
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <geekos/queue.h>
+
+
+
+void init_queue(struct gen_queue * queue) {
+ queue->num_entries = 0;
+ INIT_LIST_HEAD(&(queue->entries));
+}
+
+
+struct gen_queue * create_queue() {
+ struct gen_queue * tmp_queue = Malloc(sizeof(struct gen_queue));
+ init_queue(tmp_queue);
+ return tmp_queue;
+}
+
+void enqueue(struct gen_queue * queue, void * entry) {
+ struct queue_entry * q_entry = Malloc(sizeof(struct queue_entry));
+
+ q_entry->entry = entry;
+ list_add_tail(&(q_entry->entry_list), &(queue->entries));
+ queue->num_entries++;
+}
+
+
+void * dequeue(struct gen_queue * queue) {
+ void * entry_val = 0;
+
+ if (!list_empty(&(queue->entries))) {
+ struct list_head * q_entry = queue->entries.next;
+ struct queue_entry * tmp_entry = list_entry(q_entry, struct queue_entry, entry_list);
+
+ entry_val = tmp_entry->entry;
+ list_del(q_entry);
+ Free(tmp_entry);
+ }
+
+ return entry_val;
+}
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <geekos/ring_buffer.h>
#include <geekos/malloc.h>
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Matt Wojcik
+ * Copyright (c) 2008, Peter Kamm
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Matt Wojcik
+ * Author: Peter Kamm
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#include <geekos/rtl8139.h>
#include <geekos/debug.h>
#include <geekos/io.h>
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <geekos/serial.h>
#include <geekos/reboot.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, Lei Xia <xiaxlei@gmail.com> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, Lei Xia <xiaxlei@gmail.com>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ * Author: Lei Xia <xiaxlei@gmail.com>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <geekos/socket.h>
#include <geekos/malloc.h>
--- /dev/null
+# -*- fundamental -*-
+# This file is part of the Palacios Virtual Machine Monitor developed
+# by the V3VEE Project with funding from the United States National
+# Science Foundation and the Department of Energy.
+#
+# The V3VEE Project is a joint project between Northwestern University
+# and the University of New Mexico. You can find out more at
+# http://www.v3vee.org
+#
+# Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+# Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+# All rights reserved.
+#
+# Author: Jack Lange <jarusl@cs.northwestern.edu>
+#
+# This is free software. You are permitted to use,
+# redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+
+
+.global MyBuzzVM
+MyBuzzVM:
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %esi
+ pushl %ebx
+ inb $97, %al
+ movl $97, %ecx
+ movb %al, %bl
+ orl $2, %ebx
+ movl %eax, %esi
+.L24:
+ movb %bl, %al
+ movl %ecx, %edx
+ outb %al, %dx
+ movl $0, %edx
+.L30:
+ incl %edx
+ cmpl $999999, %edx
+ jle .L30
+ movl %esi, %eax
+ movl %ecx, %edx
+ outb %al, %dx
+ movl $0, %edx
+.L35:
+ incl %edx
+ cmpl $999999, %edx
+ jle .L35
+ jmp .L24
+
+
+
+
+
+
+
+
+
+
+
+
#include <geekos/io_defs.h>
/* PAD this currently is in nvram.c */
+/* JRL: This is completely broken
extern void deliver_timer_interrupt_to_vmm(uint_t period_us);
+*/
/* JRL Add a cpu frequency measurement */
uint_t cpu_khz_freq;
}
-
+ /* JRL: Broken,
deliver_timer_interrupt_to_vmm(1000000/HZ);
-
+ */
End_IRQ(state);
}
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
#include <geekos/vmm_stubs.h>
Init_V3(&os_hooks, &vmm_ops);
- extern char _binary_vm_kernel_start;
- PrintBoth(" Guest Load Addr: 0x%x\n", &_binary_vm_kernel_start);
-
- config_data = &_binary_vm_kernel_start;
+ extern char _binary___palacios_vm_kernel_start;
+ PrintBoth(" Guest Load Addr: 0x%x\n", &_binary___palacios_vm_kernel_start);
+
+ config_data = &_binary___palacios_vm_kernel_start;
+
vm_info = (vmm_ops).allocate_guest();
PrintBoth("Allocated Guest\n");
(vmm_ops).config_guest(vm_info, config_data);
PrintBoth("Configured guest\n");
-
- v3_hook_io_port(vm_info, 0x61, &IO_Read, &IO_Write, NULL);
+
+
//v3_hook_io_port(&vm_info, 0x05, &IO_Read, &IO_Write_to_Serial, NULL);
-
- v3_hook_io_port(vm_info, 0x400, &IO_Read, &IO_Write_to_Serial, NULL);
- v3_hook_io_port(vm_info, 0x401, &IO_Read, &IO_Write_to_Serial, NULL);
- v3_hook_io_port(vm_info, 0x402, &IO_Read, &IO_BOCHS_info, NULL);
- v3_hook_io_port(vm_info, 0x403, &IO_Read, &IO_BOCHS_debug, NULL);
+ //v3_hook_io_port(vm_info, 0x61, &IO_Read, &IO_Write, NULL);
+ //v3_hook_io_port(vm_info, 0x400, &IO_Read, &IO_Write_to_Serial, NULL);
+ //v3_hook_io_port(vm_info, 0x401, &IO_Read, &IO_Write_to_Serial, NULL);
+ //v3_hook_io_port(vm_info, 0x402, &IO_Read, &IO_BOCHS_info, NULL);
+ //v3_hook_io_port(vm_info, 0x403, &IO_Read, &IO_BOCHS_debug, NULL);
(vmm_ops).init_guest(vm_info);
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <geekos/vmm_stubs.h>
#include <geekos/serial.h>
--- /dev/null
+/**
+ * @file
+ * Ping sender module
+ *
+ */
+
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+/**
+ * This is an example of a "ping" sender (with raw API and socket API).
+ * It can be used as a start point to maintain opened a network connection, or
+ * like a network "watchdog" for your device.
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_RAW && LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/mem.h"
+#include "lwip/raw.h"
+#include "lwip/icmp.h"
+#include "lwip/netif.h"
+#include "lwip/sys.h"
+#include "lwip/sockets.h"
+#include "lwip/inet.h"
+#include "lwip/inet_chksum.h"
+
+#include "apps/ping.h"
+
+#include <geekos/timer.h>
+#include <geekos/ktypes.h>
+
+/**
+ * PING_DEBUG: Enable debugging for PING.
+ */
+#ifndef PING_DEBUG
+#define PING_DEBUG LWIP_DBG_ON
+#endif
+
+/** ping target - should be a "struct ip_addr" */
+#ifndef PING_TARGET
+#define PING_TARGET (netif_default?netif_default->gw:ip_addr_any)
+#endif
+
+/** ping receive timeout - in milliseconds */
+#ifndef PING_RCV_TIMEO
+#define PING_RCV_TIMEO 1000
+#endif
+
+/** ping delay - in milliseconds */
+#ifndef PING_DELAY
+#define PING_DELAY 1000
+#endif
+
+/** ping identifier - must fit on a u16_t */
+#ifndef PING_ID
+#define PING_ID 0xAFAF
+#endif
+
+/** ping additional data size to include in the packet */
+#ifndef PING_DATA_SIZE
+#define PING_DATA_SIZE 32
+#endif
+
+/** ping result action - no default action */
+#ifndef PING_RESULT
+#define PING_RESULT(ping_ok)
+#endif
+
+/* ping variables */
+static u16_t ping_seq_num;
+static u32_t ping_time;
+
+#if NO_SYS
+/* port-defined functions used for timer execution */
+void sys_msleep(u32_t ms);
+u32_t sys_now();
+#endif /* NO_SYS */
+
+/** Prepare a echo ICMP request */
+static void
+ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
+{
+ int i;
+
+ ICMPH_TYPE_SET(iecho,ICMP_ECHO);
+ ICMPH_CODE_SET(iecho, 0);
+ iecho->chksum = 0;
+ iecho->id = PING_ID;
+ iecho->seqno = htons(++ping_seq_num);
+ iecho->chksum = inet_chksum(iecho, len);
+
+ /* fill the additional data buffer with some data */
+ for(i = 0; i < PING_DATA_SIZE; i++) {
+ ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = i;
+ }
+}
+
+#if LWIP_SOCKET
+
+/* Ping using the socket ip */
+static err_t
+ping_send(int s, struct ip_addr *addr)
+{
+ int err;
+ struct icmp_echo_hdr *iecho;
+ struct sockaddr_in to;
+ size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE;
+
+ if (!(iecho = mem_malloc(ping_size))) {
+ return ERR_MEM;
+ }
+
+ ping_prepare_echo(iecho, ping_size);
+
+ to.sin_len = sizeof(to);
+ to.sin_family = AF_INET;
+ to.sin_addr.s_addr = addr->addr;
+
+ err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to));
+
+ mem_free(iecho);
+
+ return (err ? ERR_OK : ERR_VAL);
+}
+
+static void
+ping_recv(int s)
+{
+ char buf[64];
+ int fromlen, len;
+ struct sockaddr_in from;
+ struct ip_hdr *iphdr;
+ struct icmp_echo_hdr *iecho;
+
+ while((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0) {
+ if (len >= (sizeof(struct ip_hdr)+sizeof(struct icmp_echo_hdr))) {
+ LWIP_DEBUGF( PING_DEBUG, ("ping: recv "));
+ ip_addr_debug_print(PING_DEBUG, (struct ip_addr *)&(from.sin_addr));
+ LWIP_DEBUGF( PING_DEBUG, (" %lu ms\n", (sys_now()-ping_time)));
+
+ iphdr = (struct ip_hdr *)buf;
+ iecho = (struct icmp_echo_hdr *)(buf+(IPH_HL(iphdr) * 4));
+ if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) {
+ /* do some ping result processing */
+ PING_RESULT((ICMPH_TYPE(iecho) == ICMP_ER));
+ return;
+ } else {
+ LWIP_DEBUGF( PING_DEBUG, ("ping: drop\n"));
+ }
+ }
+ }
+
+ if (len == 0) {
+ LWIP_DEBUGF( PING_DEBUG, ("ping: recv - %lu ms - timeout\n", (sys_now()-ping_time)));
+ }
+
+ /* do some ping result processing */
+ PING_RESULT(0);
+}
+
+static void
+ping_thread(void *arg)
+{
+ int s;
+ int timeout = PING_RCV_TIMEO;
+ struct ip_addr ping_target;
+
+ LWIP_UNUSED_ARG(arg);
+
+ if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) {
+ return;
+ }
+
+ lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
+
+ while (1) {
+ ping_target = PING_TARGET;
+
+ if (ping_send(s, &ping_target) == ERR_OK) {
+ LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
+ ip_addr_debug_print(PING_DEBUG, &ping_target);
+ LWIP_DEBUGF( PING_DEBUG, ("\n"));
+
+ ping_time = sys_now();
+ ping_recv(s);
+ } else {
+ LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
+ ip_addr_debug_print(PING_DEBUG, &ping_target);
+ LWIP_DEBUGF( PING_DEBUG, (" - error\n"));
+ }
+ sys_msleep(PING_DELAY);
+ }
+}
+
+#else /* LWIP_SOCKET */
+
+/* Ping using the raw ip */
+static u8_t
+ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *addr)
+{
+ struct icmp_echo_hdr *iecho;
+
+ if (pbuf_header( p, -PBUF_IP_HLEN)==0) {
+ iecho = p->payload;
+
+ if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) {
+ LWIP_DEBUGF( PING_DEBUG, ("ping: recv "));
+ ip_addr_debug_print(PING_DEBUG, addr);
+ LWIP_DEBUGF( PING_DEBUG, (" %lu ms\n", (sys_now()-ping_time)));
+
+ /* do some ping result processing */
+ PING_RESULT(1);
+ }
+ }
+
+ return 1; /* eat the event */
+}
+
+static void
+ping_send(struct raw_pcb *raw, struct ip_addr *addr)
+{
+ struct pbuf *p;
+ struct icmp_echo_hdr *iecho;
+ size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE;
+
+ if (!(p = pbuf_alloc(PBUF_IP, ping_size, PBUF_RAM))) {
+ return;
+ }
+ if ((p->len == p->tot_len) && (p->next == NULL)) {
+ iecho = p->payload;
+
+ ping_prepare_echo(iecho, ping_size);
+
+ raw_sendto(raw, p, addr);
+ ping_time = sys_now();
+ }
+ pbuf_free(p);
+}
+
+static void
+ping_timeout(void *arg)
+{
+ struct raw_pcb *pcb = (struct raw_pcb*)arg;
+ struct ip_addr ping_target = PING_TARGET;
+
+ LWIP_ASSERT("ping_timeout: no pcb given!", pcb != NULL);
+
+ LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
+ ip_addr_debug_print(PING_DEBUG, &ping_target);
+ LWIP_DEBUGF( PING_DEBUG, ("\n"));
+
+ ping_send(pcb, &ping_target);
+
+ sys_timeout(PING_DELAY, ping_timeout, pcb);
+}
+
+static void
+ping_raw_init(void)
+{
+ struct raw_pcb *pcb;
+
+ if (!(pcb = raw_new(IP_PROTO_ICMP))) {
+ return;
+ }
+
+ raw_recv(pcb, ping_recv, NULL);
+ raw_bind(pcb, IP_ADDR_ANY);
+ sys_timeout(PING_DELAY, ping_timeout, pcb);
+}
+
+#endif /* LWIP_SOCKET */
+
+void
+ping_init(void)
+{
+#if LWIP_SOCKET
+ sys_thread_new("ping_thread", ping_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+#else /* LWIP_SOCKET */
+ ping_raw_init();
+#endif /* LWIP_SOCKET */
+}
+
+
+u32_t
+sys_now()
+{
+ ulong_t msec;
+
+ msec = clock_time();
+
+ return msec;
+}
+
+#endif /* LWIP_RAW && LWIP_ICMP */
--- /dev/null
+/**\r
+ * @file\r
+ * Ethernet Interface for ne2k device\r
+ *\r
+ * Lei Xia (lxia@northwestern.edu\r
+ */\r
+\r
+#include "lwip/opt.h"\r
+ \r
+\r
+#include "lwip/def.h"\r
+#include "lwip/mem.h"\r
+#include "lwip/pbuf.h"\r
+#include "lwip/sys.h"\r
+#include <lwip/stats.h>\r
+#include <lwip/snmp.h>\r
+#include "netif/etharp.h"\r
+#include "netif/ppp_oe.h"\r
+#include "lwip/netifapi.h"\r
+#include "netif/ne2kif.h"\r
+\r
+\r
+#include <geekos/ne2k.h>\r
+#include <geekos/ktypes.h>\r
+#include <geekos/debug.h>\r
+\r
+\r
+struct netif ne2kif; \r
+\r
+/**\r
+ * This function should do the actual transmission of the packet. The packet is\r
+ * contained in the pbuf that is passed to the function. This pbuf\r
+ * might be chained.\r
+ *\r
+ * @param netif the lwip network interface structure for this ethernetif\r
+ * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)\r
+ * @return ERR_OK if the packet could be sent\r
+ * an err_t value if the packet couldn't be sent\r
+ *\r
+ * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to\r
+ * strange results. You might consider waiting for space in the DMA queue\r
+ * to become availale since the stack doesn't retry to send a packet\r
+ * dropped because of memory failure (except for the TCP timers).\r
+ */\r
+\r
+err_t\r
+ne2kif_output(struct netif *netif, struct pbuf *p)\r
+{\r
+ struct pbuf *q;\r
+ int size, offset, remlen;\r
+ uchar_t *packet;\r
+ \r
+#if ETH_PAD_SIZE\r
+ pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */\r
+#endif\r
+\r
+ size = p->tot_len;\r
+ offset = 0;\r
+ remlen = size;\r
+\r
+ packet = (uchar_t *)Malloc (remlen);\r
+\r
+ for(q = p; q != NULL && remlen >0; q = q->next) {\r
+ /* Send the data from the pbuf to the interface, one pbuf at a\r
+ time. The size of the data in each pbuf is kept in the ->len\r
+ variable. */\r
+\r
+ memcpy(packet+offset, q->payload, q->len < remlen? q->len:remlen);\r
+ remlen -= q->len;\r
+ offset += q->len;\r
+ \r
+ }\r
+ NE2K_Send_Packet(packet, size);\r
+\r
+ //signal that packet should be sent();\r
+\r
+#if ETH_PAD_SIZE\r
+ pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */\r
+#endif\r
+ \r
+ LINK_STATS_INC(link.xmit);\r
+\r
+ return ERR_OK;\r
+}\r
+\r
+\r
+/**\r
+ * This function should be called when a packet is ready to be read\r
+ * from the interface. It uses the function low_level_input() that\r
+ * should handle the actual reception of bytes from the network\r
+ * interface. Then the type of the received packet is determined and\r
+ * the appropriate input function is called.\r
+ *\r
+ * @param netif the lwip network interface structure for this ethernetif\r
+ */\r
+void\r
+ne2kif_input(struct NE2K_Packet_Info * info, uchar_t * pkt)\r
+{\r
+ struct pbuf *p, *q;\r
+ uint_t offset;\r
+ uint_t len, rlen;\r
+ \r
+ len = info->size; \r
+\r
+ PrintBoth("Ne2k: Packet REceived\n");\r
+\r
+#if ETH_PAD_SIZE\r
+ len += ETH_PAD_SIZE; // allow room for Ethernet padding \r
+#endif\r
+\r
+ p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);\r
+ \r
+ if (p != NULL) {\r
+\r
+#if ETH_PAD_SIZE\r
+ pbuf_header(p, -ETH_PAD_SIZE); // drop the padding word \r
+#endif\r
+\r
+ // iterate over the pbuf chain until it has read the entire packet into the pbuf.\r
+ for(offset = 0, q = p; q != NULL && rlen > 0; q = q->next) {\r
+ memcpy(q->payload, pkt+offset, rlen > q->len? q->len: rlen);\r
+ rlen -= q->len;\r
+ offset += q->len;\r
+ }\r
+\r
+#if ETH_PAD_SIZE\r
+ pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */\r
+#endif\r
+\r
+ LINK_STATS_INC(link.recv);\r
+ } else {\r
+ LINK_STATS_INC(link.memerr);\r
+ LINK_STATS_INC(link.drop);\r
+ }\r
+\r
+ Free(pkt);\r
+ \r
+ if (p == NULL) return;\r
+ /* points to packet payload, which starts with an Ethernet header */\r
+ //ethhdr = p->payload;\r
+\r
+ /* full packet send to tcpip_thread to process */\r
+ if (ne2kif.input(p, &ne2kif)!=ERR_OK)\r
+ { LWIP_DEBUGF(NETIF_DEBUG, ("ne2kif_input: IP input error\n"));\r
+ pbuf_free(p);\r
+ p = NULL;\r
+ }\r
+\r
+#if 0\r
+ switch (htons(ethhdr->type)) {\r
+ /* IP or ARP packet? */\r
+ case ETHTYPE_IP:\r
+ case ETHTYPE_ARP:\r
+#if PPPOE_SUPPORT\r
+ /* PPPoE packet? */\r
+ case ETHTYPE_PPPOEDISC:\r
+ case ETHTYPE_PPPOE:\r
+#endif /* PPPOE_SUPPORT */\r
+ \r
+ break;\r
+\r
+ default:\r
+ pbuf_free(p);\r
+ p = NULL;\r
+ break;\r
+ }\r
+#endif\r
+\r
+}\r
+\r
+/**\r
+ * Should be called at the beginning of the program to set up the\r
+ * network interface. It calls the function low_level_init() to do the\r
+ * actual setup of the hardware.\r
+ *\r
+ * This function should be passed as a parameter to netif_add().\r
+ *\r
+ * @param netif the lwip network interface structure for this ethernetif\r
+ * @return ERR_OK if the loopif is initialized\r
+ * ERR_MEM if private data couldn't be allocated\r
+ * any other err_t on error\r
+ */\r
+err_t\r
+ne2kif_init(struct netif *netif)\r
+{\r
+\r
+#if LWIP_NETIF_HOSTNAME\r
+ /* Initialize interface hostname */\r
+ netif->hostname = "lwip";\r
+#endif /* LWIP_NETIF_HOSTNAME */\r
+\r
+ /*\r
+ * Initialize the snmp variables and counters inside the struct netif.\r
+ * The last argument should be replaced with your link speed, in units\r
+ * of bits per second.\r
+ */\r
+ NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);\r
+\r
+ netif->state = NULL;\r
+ netif->name[0] = 'n';\r
+ netif->name[1] = 'e';\r
+ /* We directly use etharp_output() here to save a function call.\r
+ * You can instead declare your own function an call etharp_output()\r
+ * from it if you have to do some checks before sending (e.g. if link\r
+ * is available...) */\r
+ netif->output = etharp_output;\r
+ netif->linkoutput = ne2kif_output;\r
+ \r
+\r
+ /* set MAC hardware address length */\r
+ netif->hwaddr_len = ETHARP_HWADDR_LEN;\r
+\r
+ /* set MAC hardware address */\r
+ netif->hwaddr[0] = PHY_ADDR1;\r
+ netif->hwaddr[1] = PHY_ADDR2;\r
+ netif->hwaddr[2] = PHY_ADDR3;\r
+ netif->hwaddr[3] = PHY_ADDR4;\r
+ netif->hwaddr[4] = PHY_ADDR5;\r
+ netif->hwaddr[5] = PHY_ADDR6;\r
+\r
+ /* maximum transfer unit */\r
+ netif->mtu = 1500;\r
+ \r
+ /* device capabilities */\r
+ /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */\r
+ netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;\r
+\r
+ //initate ne2k hardware\r
+ Init_Ne2k(&ne2kif_input);\r
+\r
+ return ERR_OK;\r
+}\r
#
# The setup code needs to copy it up to this address and jump there
#
-KERNEL_BASE_ADDR := 0x00100000
-# Kernel entry point function
-KERNEL_ENTRY = $(SYM_PFX)Main
+
PROJECT_ROOT := ..
ifeq ($(DECODER),XED)
DECODER_SRCS := vmm_xed.c
DECODER_FLAGS := -L../lib/xed
-DECODER_LIBS := -lxed
+DECODER_LIBS := $(PROJECT_ROOT)/lib/xed/libxed.a
else
# This is an error
endif
-#
-#TCPSTACK, uIP is used currently
-#
-UIP=OFF
-
-#
-#LWIP, ON -- used, OFF -- not used
-#
-LWIP=ON
-#
-#RAMDISK
-#
-RAMDISK_SRCS=
-BOOT_FLAGS=
-ifeq ($(RAMDISK_BOOT),1)
-BOOT_FLAGS := $(BOOT_FLAGS) -DRAMDISK_BOOT
-RAMDISK_SRCS := ramdisk.c cdrom.c
-endif
# List of targets to build by default.
# These targets encompass everything needed to boot
# and run GeekOS.
-ALL_TARGETS := vmm.img vm_kernel
-
-
-# Kernel source files
-KERNEL_C_SRCS := idt.c int.c trap.c irq.c io.c \
- blockdev.c ide.c ne2k.c \
- keyboard.c screen.c timer.c \
- mem.c crc32.c \
- gdt.c tss.c segment.c \
- bget.c malloc.c \
- synch.c kthread.c \
- serial.c reboot.c \
- paging.c \
- debug.c vmm_stubs.c vm.c pci.c\
- queue.c socket.c net.c ring_buffer.c \
- main.c
-
+ALL_TARGETS := vmm vm_kernel
-# Kernel object files built from C source files
-KERNEL_C_OBJS := $(KERNEL_C_SRCS:%.c=geekos/%.o)
-# Kernel assembly files
-KERNEL_ASM_SRCS := lowlevel.asm
-KERNEL_GAS_SRCS := testvm.s udivdi3.s
-# Kernel object files build from assembler source files
-KERNEL_ASM_OBJS := $(KERNEL_ASM_SRCS:%.asm=geekos/%.o)
-KERNEL_GAS_OBJS := $(KERNEL_GAS_SRCS:%.s=geekos/%.o)
-
-# All kernel object files
-KERNEL_OBJS := $(KERNEL_C_OBJS) \
- $(KERNEL_ASM_OBJS) $(KERNEL_GAS_OBJS)
-
-# Common library source files.
-# This library is linked into both the kernel and user programs.
-# It provides string functions and generic printf()-style
-# formatted output.
-COMMON_C_SRCS := fmtout.c string.c memmove.c
-
-# Common library object files.
-COMMON_C_OBJS := $(COMMON_C_SRCS:%.c=common/%.o)
-
-VMM_ASM_SRCS := svm_lowlevel.asm \
+VMM_ASM_SRCS := svm_lowlevel.asm vmm_lowlevel.asm\
# vmx_lowlevel.asm
VMM_ASM_OBJS := $(VMM_ASM_SRCS:%.asm=palacios/%.o)
+XED_C_SRCS := v3-xed-compat.c
-DEVICE_C_SRCS := generic.c keyboard.c nvram.c timer.c simple_pic.c 8259a.c 8254.c serial.c $(RAMDISK_SRCS)
+XED_C_OBJS := $(XED_C_SRCS:%.c=xed/%.o)
-DEVICE_C_OBJS := $(DEVICE_C_SRCS:%.c=devices/%.o)
+XED_GAS_SRCS := v3-udiv-compat.s
-DEVICE_OBJS := $(DEVICE_C_OBJS)
+XED_GAS_OBJS := $(XED_GAS_SRCS:%.s=xed/%.o)
-V3LIBS := $(DECODER_LIBS)
+XED_OBJS := $(XED_C_OBJS) $(XED_GAS_OBJS)
+DEVICE_C_SRCS := generic.c keyboard.c nvram.c timer.c simple_pic.c 8259a.c 8254.c serial.c ramdisk.c cdrom.c
-ifeq ($(UIP),ON)
- UIP_C_SRCS := psock.c timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-neighbor.c uip-split.c resolv.c
- UIP_C_OBJS := $(UIP_C_SRCS:%.c=net/%.o)
-else
- UIP_C_SRCS :=
- UIP_C_OBJS :=
-endif
+DEVICE_C_OBJS := $(DEVICE_C_SRCS:%.c=devices/%.o)
-ifeq ($(LWIP),ON)
- LWIP_OBJS := lwip/*.o
- CC_LWIP_OPTS := -I$(PROJECT_ROOT)/include/lwip -I$(PROJECT_ROOT)/include/lwip/ipv4 -I$(PROJECT_ROOT)/include/libc -DLWIP_DEBUG
-else
- LWIP_OBJS :=
- CC_LWIP_OPTS :=
-endif
+DEVICE_OBJS := $(DEVICE_C_OBJS)
+
+V3LIBS := $(DECODER_LIBS)
-TCPSTACK_OBJS := $(UIP_C_OBJS) $(LWIP_OBJS)
TARGET_CC := $(TARGET_CC_PREFIX)gcc
#TARGET_CC := $(TARGET_CC_PREFIX)gcc34 -m32
-# Host C compiler. This is used to compile programs to execute on
-# the host platform, not the target (x86) platform. On x86/ELF
-# systems, such as Linux and FreeBSD, it can generally be the same
-# as the target C compiler.
-HOST_CC := gcc
# Target linker. GNU ld is probably to only one that will work.
TARGET_LD := $(TARGET_CC_PREFIX)ld -melf_i386
# ----------------------------------------------------------------------
# Flags used for all C source files
-GENERAL_OPTS := -O -Wall $(EXTRA_C_OPTS) $(VMM_FLAGS) $(BOOT_FLAGS) -fPIC
+GENERAL_OPTS := -O -Wall $(EXTRA_C_OPTS) $(VMM_FLAGS) -fPIC #-fvisibility=hidden
CC_GENERAL_OPTS := $(GENERAL_OPTS) -Werror
-# Flags used for kernel C source files
-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__ -D__V3_32BIT__ $(DECODER_FLAGS) $(JRLDEBUG)
# Flags used for VMM C ASM files
NASM_VMM_OPTS := -I$(PROJECT_ROOT)/src/palacios/ -f elf $(EXTRA_NASM_OPTS)
-# Flags user for kernel assembly files
-NASM_KERNEL_OPTS := -I$(PROJECT_ROOT)/src/geekos/ -f elf $(EXTRA_NASM_OPTS)
-# Flags used for common library and libc source files
-CC_USER_OPTS := -I$(PROJECT_ROOT)/include -I$(PROJECT_ROOT)/include/libc \
- $(EXTRA_CC_USER_OPTS)
+
+
# Flags passed to objcopy program (strip unnecessary sections from kernel.exe)
OBJCOPY_FLAGS := -R .dynamic -R .note -R .comment
# Describes how to compile the source files.
# ----------------------------------------------------------------------
-# Compilation of kernel C source files
-geekos/%.o : geekos/%.c
- $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) $(CC_LWIP_OPTS) $< -o geekos/$*.o
-
-
-# Compilation of kernel assembly source files
-geekos/%.o : geekos/%.asm
- $(NASM) $(NASM_KERNEL_OPTS) $< -o geekos/$*.o
-
-# Compilation of test VM
-geekos/%.o : geekos/%.s
- $(AS) $< -o geekos/$*.o
-
-geekos/%.o : geekos/%.S
- $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) $< -o geekos/$*.o
-
-# Compilation of common library C source files
-common/%.o : common/%.c
- $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_USER_OPTS) $< -o common/$*.o
palacios/%.o : palacios/%.c
$(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_VMM_OPTS) $< -o palacios/$*.o
devices/%.o : devices/%.asm
$(NASM) $(NASM_VMM_OPTS) $< -o devices/$*.o
-net/%.o : net/%.c
- $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_USER_OPTS) $< -o net/$*.o
+
+xed/%.o : xed/%.c
+ $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_VMM_OPTS) $< -o xed/$*.o
+
+xed/%.o : xed/%.s
+ $(AS) $< -o xed/$*.o
+
# ----------------------------------------------------------------------
# Targets -
#geekos/test: geekos/test.o geekos/vmcs.o geekos/vmx_lowlevel.o
# $(CC) geekos/test.o geekos/vmcs.o geekos/vmx_lowlevel.o -o geekos/test
-# Standard floppy image - just boots the kernel
-fd.img : geekos/fd_boot.bin geekos/setup.bin geekos/kernel.bin
- cat geekos/fd_boot.bin geekos/setup.bin geekos/kernel.bin > _temp
- $(PAD) _temp 512
- cp _temp fd.img
-vmm.img : fd.img
- cp fd.img vmm.img
- $(PAD) vmm.img 1474560
rombios_link:
ln -s -f ../src/vmboot/rombios/BIOS-bochs-latest rombios
inter1: force_payload force_lwip
-make clean
-world: inter1 vmm.img
-
-# make ready to boot over PXE
-pxe: vmm.img
- cp vmm.img /tftpboot/vmm.img
+world: inter1 vmm
-run: vmm.img
- /usr/local/qemu/bin/qemu-system-x86_64 -m 1024 -serial file:serial.out -cdrom puppy.iso -fda vmm.img
+vmm: palacios/vmm.lib
-# Floppy boot sector (first stage boot loader).
-geekos/fd_boot.bin : geekos/setup.bin geekos/kernel.bin $(PROJECT_ROOT)/src/geekos/fd_boot.asm
- $(NASM) -f bin \
- -I$(PROJECT_ROOT)/src/geekos/ \
- -DNUM_SETUP_SECTORS=`$(NUMSECS) geekos/setup.bin` \
- -DNUM_KERN_SECTORS=`$(NUMSECS) geekos/kernel.bin` \
- -DSECTORS_PER_TRACK=`$(FD_SECTORS_PER_TRACK) geekos/kernel.bin geekos/setup.bin` \
- $(PROJECT_ROOT)/src/geekos/fd_boot.asm \
- -o $@
-
-# Setup program (second stage boot loader).
-geekos/setup.bin : geekos/kernel.bin $(PROJECT_ROOT)/src/geekos/setup.asm
- $(NASM) -f bin \
- -I$(PROJECT_ROOT)/src/geekos/ \
- -DENTRY_POINT=0x`egrep 'Main$$' geekos/kernel.syms |awk '{print $$1}'` \
- -DVMM_SIZE=`$(NUMSECS) geekos/kernel.bin` \
- $(PROJECT_ROOT)/src/geekos/setup.asm \
- -o $@
- $(PAD) $@ 2048
-
# Loadable (flat) kernel image.
-geekos/kernel.bin : geekos/kernel.exe
- $(TARGET_OBJCOPY) $(OBJCOPY_FLAGS) -S -O binary geekos/kernel.exe geekos/kernel.bin
- $(PAD) $@ 512
+palacios/vmm.bin : palacios/vmm.lib
+ $(TARGET_OBJCOPY) $(OBJCOPY_FLAGS) -S -O binary palacios/vmm.lib palacios/vmm.bin
+
# The kernel executable and symbol map.
-geekos/kernel.exe : $(KERNEL_OBJS) $(COMMON_C_OBJS) $(VMM_OBJS) $(DEVICE_OBJS) $(TCPSTACK_OBJS) vm_kernel
- $(TARGET_LD) -o geekos/kernel.exe -Ttext $(KERNEL_BASE_ADDR) -e $(KERNEL_ENTRY) \
- $(DECODER_FLAGS) \
- $(KERNEL_OBJS) $(COMMON_C_OBJS) $(VMM_OBJS) $(DEVICE_OBJS) $(V3LIBS) $(TCPSTACK_OBJS) -b binary vm_kernel
- $(TARGET_NM) geekos/kernel.exe > geekos/kernel.syms
+palacios/vmm.lib: $(VMM_OBJS) $(DEVICE_OBJS) $(XED_OBJS) vm_kernel
+# $(TARGET_LD) -o palacios/vmm.lib \
+# $(DECODER_FLAGS) \
+# $(VMM_OBJS) $(DEVICE_OBJS) $(XED_OBJS) $(V3LIBS) -b binary vm_kernel
+# $(TARGET_NM) palacios/vmm.lib > palacios/vmm.syms
+ $(TARGET_AR) rcs libv3vee.a \
+ $(VMM_OBJS) $(DEVICE_OBJS) $(XED_OBJS)
-force:
+force:
-#vm_kernel: force
-# $(PAD) vm_kernel 512
-# @echo "VM kernel lives at 0x100000 and is" `$(NUMSECS) vm_kernel` "sectors long"
# Clean build directories of generated files
clean :
- for d in geekos common libc user tools palacios devices net; do \
+ for d in palacios devices; do \
(cd $$d && rm -f *); \
done
# Build header file dependencies, so source files are recompiled when
# header files they depend on are modified.
depend : $(GENERATED_LIBC_SRCS)
- $(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) \
- $(KERNEL_C_SRCS:%.c=$(PROJECT_ROOT)/src/geekos/%.c) \
- | $(PERL) -n -e 's,^(\S),geekos/$$1,;print' \
- > depend.mak
- $(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_USER_OPTS) \
- $(COMMON_C_SRCS:%.c=$(PROJECT_ROOT)/src/common/%.c) \
- | $(PERL) -n -e 's,^(\S),common/$$1,;print' \
- >> depend.mak
+
$(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) \
$(VMM_C_SRCS:%.c=$(PROJECT_ROOT)/src/palacios/%.c) \
| $(PERL) -n -e 's,^(\S),palacios/$$1,;print' \
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#ifndef __8237_DMA_H
#define __8237_DMA_H
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __8254_H
#define __8254_H
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __8259A_H
#define __8259A_H
+
/*
- * Zheng Cui
- * cuizheng@cs.unm.edu
- * July 2008
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Zheng Cui<cuizheng@cs.unm.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Zheng Cui<cuizheng@cs.unm.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
#ifndef __DEVICES_CDROM_H_
#define __DEVICES_CDROM_H_
-#include <geekos/ktypes.h>
+#include <devices/ramdisk.h>
+#include <devices/ide.h>
+#include <palacios/vmm_types.h>
+
-typedef unsigned int rd_bool;
-typedef uchar_t Bit8u;
-typedef ushort_t Bit16u;
-typedef uint_t Bit32u;
-typedef ullong_t Bit64u;
-#define uint8 Bit8u
-#define uint16 Bit16u
-#define uint32 Bit32u
struct cdrom_interface;
/*
* Read CD TOC. Returns false if start track is out of bounds.
*/
- rd_bool (*read_toc)(struct cdrom_interface *cdrom, uint8* buf, int* length, rd_bool msf, int start_track);
+ rd_bool (*read_toc)(struct cdrom_interface * cdrom, uint8_t * buf, int* length, rd_bool msf, int start_track);
/*
* Return CD-ROM capacity (in 2048 byte frames)
*/
- uint32 (*capacity)(struct cdrom_interface *cdrom);
+ uint32_t (*capacity)(struct cdrom_interface *cdrom);
/*
* Read a single block from the CD
*/
- void (*read_block)(struct cdrom_interface *cdrom, uint8* buf, int lba);
+ void (*read_block)(struct cdrom_interface *cdrom, uint8_t* buf, int lba);
/*
* Start (spin up) the CD.
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+#ifndef __GENERIC_H__
+#define __GENERIC_H__
-#ifndef __GENERIC_H
-#define __GENERIC_H
#include <palacios/vm_dev.h>
#define GENERIC_PRINT_AND_PASSTHROUGH 0
#define GENERIC_PRINT_AND_IGNORE 1
-// A port range is low..high, inclusive, third value is one of the above
-typedef uint_t generic_port_range_type[3];
-// A memory range is low..high, inclusive, flags
-typedef void *generic_address_range_type[3];
-// An interrupt ory map range is low..high, inclusive, flags
-typedef uint_t generic_irq_range_type[3];
+
+int v3_generic_add_port_range(struct vm_device * dev, uint_t start, uint_t end, uint_t type);
+int v3_generic_add_mem_range(struct vm_device * dev, void * start, void * end, uint_t type);
+int v3_generic_add_irq_range(struct vm_device * dev, uint_t start, uint_t end, uint_t type);
// The lists given are null terminated
-struct vm_device *create_generic(generic_port_range_type port_ranges[],
- generic_address_range_type addess_ranges[],
- generic_irq_range_type irq_ranges[]);
+struct vm_device * create_generic();
#endif
--- /dev/null
+/*
+ * Copyright (C) 2002 MandrakeSoft S.A.
+ *
+ * MandrakeSoft S.A.
+ * 43, rue d'Aboukir
+ * 75002 Paris - France
+ * http://www.linux-mandrake.com/
+ * http://www.mandrakesoft.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Major modifications made for the V3VEE project
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Zheng Cui <cuizheng@cs.unm.edu>
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved for original changes
+ *
+ */
+
+#ifndef __IDE_H__
+#define __IDE_H__
+
+
+#ifdef __V3VEE__
+#include <palacios/vmm_types.h>
+
+#ifdef __V3_32BIT__
+typedef long off_t;
+typedef sint32_t ssize_t;
+typedef unsigned int rd_bool;
+typedef uchar_t Bit8u;
+typedef ushort_t Bit16u;
+typedef uint32_t Bit32u;
+typedef uint64_t Bit64u;
+#endif
+
+
+#define MAX_ATA_CHANNEL 4
+
+typedef enum _sense {
+ SENSE_NONE = 0,
+ SENSE_NOT_READY = 2,
+ SENSE_ILLEGAL_REQUEST = 5,
+ SENSE_UNIT_ATTENTION = 6
+} sense_t ;
+
+typedef enum _asc {
+ ASC_INV_FIELD_IN_CMD_PACKET = 0x24,
+ ASC_MEDIUM_NOT_PRESENT = 0x3a,
+ ASC_SAVING_PARAMETERS_NOT_SUPPORTED = 0x39,
+ ASC_LOGICAL_BLOCK_OOR = 0x21
+} asc_t ;
+
+
+
+typedef struct {
+ unsigned cylinders;
+ unsigned heads;
+ unsigned sectors;
+} device_image_t;
+
+
+
+
+struct interrupt_reason_t {
+ unsigned c_d : 1;
+ unsigned i_o : 1;
+ unsigned rel : 1;
+ unsigned tag : 5;
+};
+
+
+struct controller_status {
+ rd_bool busy;
+ rd_bool drive_ready;
+ rd_bool write_fault;
+ rd_bool seek_complete;
+ rd_bool drq;
+ rd_bool corrected_data;
+ rd_bool index_pulse;
+ unsigned int index_pulse_count;
+ rd_bool err;
+};
+
+
+
+
+
+struct sense_info_t {
+ sense_t sense_key;
+
+ struct {
+ Bit8u arr[4];
+ } information;
+
+ struct {
+ Bit8u arr[4];
+ } specific_inf;
+
+ struct {
+ Bit8u arr[3];
+ } key_spec;
+
+ Bit8u fruc;
+ Bit8u asc;
+ Bit8u ascq;
+};
+
+
+struct error_recovery_t {
+ unsigned char data[8];
+};
+
+struct cdrom_t {
+ rd_bool ready;
+ rd_bool locked;
+
+ struct cdrom_interface * cd;
+
+ uint32_t capacity;
+ int next_lba;
+ int remaining_blocks;
+
+ struct currentStruct {
+ struct error_recovery_t error_recovery;
+ } current;
+
+};
+
+struct atapi_t {
+ uint8_t command;
+ int drq_bytes;
+ int total_bytes_remaining;
+};
+
+
+typedef enum { IDE_NONE, IDE_DISK, IDE_CDROM } device_type_t;
+
+struct controller_t {
+ struct controller_status status;
+ Bit8u error_register;
+ Bit8u head_no;
+
+ union {
+ Bit8u sector_count;
+ struct interrupt_reason_t interrupt_reason;
+ };
+
+
+ Bit8u sector_no;
+
+ union {
+ Bit16u cylinder_no;
+ Bit16u byte_count;
+ };
+
+ Bit8u buffer[2048];
+ Bit32u buffer_index;
+ Bit32u drq_index;
+ Bit8u current_command;
+ Bit8u sectors_per_block;
+ Bit8u lba_mode;
+
+ struct {
+ rd_bool reset; // 0=normal, 1=reset controller
+ rd_bool disable_irq; // 0=allow irq, 1=disable irq
+ } control;
+
+ Bit8u reset_in_progress;
+ Bit8u features;
+};
+
+
+
+
+struct drive_t {
+ device_image_t hard_drive;
+ device_type_t device_type;
+ // 512 byte buffer for ID drive command
+ // These words are stored in native word endian format, as
+ // they are fetched and returned via a return(), so
+ // there's no need to keep them in x86 endian format.
+ Bit16u id_drive[256];
+
+ struct controller_t controller;
+ struct cdrom_t cdrom;
+ struct sense_info_t sense;
+ struct atapi_t atapi;
+
+ Bit8u model_no[41];
+};
+
+
+// FIXME:
+// For each ATA channel we should have one controller struct
+// and an array of two drive structs
+struct channel_t {
+ struct drive_t drives[2];
+ unsigned drive_select;
+
+ Bit16u ioaddr1;
+ Bit16u ioaddr2;
+ Bit8u irq;
+};
+
+
+
+struct ramdisk_t {
+ struct channel_t channels[MAX_ATA_CHANNEL];
+};
+
+
+
+
+
+
+
+
+
+#endif // ! __V3VEE__
+
+
+#endif
+
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __KEYBOARD_H
#define __KEYBOARD_H
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __NVRAM_H
#define __NVRAM_H
/*
- * Zheng Cui
- * cuizheng@cs.unm.edu
- * July 2008
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Zheng Cui <cuizheng@cs.unm.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Zheng Cui <cuizheng@cs.unm.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
#ifndef __DEVICES_RAMDISK_H_
#define __DEVICES_RAMDISK_H_
-#include <stddef.h> //for off_t in C99
-#include <sys/types.h> //for size_t
-#include <geekos/ktypes.h>
-#include <devices/cdrom.h>
+#include <palacios/vmm_types.h>
#include <palacios/vm_dev.h>
-#define INDEX_PULSE_CYCLE 10
-#define MAX_ATA_CHANNEL 4
-#define RD_LITTLE_ENDIAN
-#define INTR_REASON_BIT_ERR 0x01
-#define UNABLE_FIND_TAT_CHANNEL_ERR 0x02
-#define DRQ_ERR 0x03
-#define READ_BUF_GT_512 0x04
-typedef enum _sense {
- SENSE_NONE = 0, SENSE_NOT_READY = 2, SENSE_ILLEGAL_REQUEST = 5,
- SENSE_UNIT_ATTENTION = 6
-} sense_t ;
-
-typedef enum _asc {
- ASC_INV_FIELD_IN_CMD_PACKET = 0x24,
- ASC_MEDIUM_NOT_PRESENT = 0x3a,
- ASC_SAVING_PARAMETERS_NOT_SUPPORTED = 0x39,
- ASC_LOGICAL_BLOCK_OOR = 0x21
-} asc_t ;
-
-
-// FLAT MODE
-// Open a image. Returns non-negative if successful.
-//int open (const char* pathname);
-
-// Open an image with specific flags. Returns non-negative if successful.
-int rd_open (const char* pathname, int flags);
-
-// Close the image.
-void rd_close ();
-
-// Position ourselves. Return the resulting offset from the
-// beginning of the file.
-off_t rd_lseek (off_t offset, int whence);
-
-// Read count bytes to the buffer buf. Return the number of
-// bytes read (count).
-ssize_t rd_read (void* buf, size_t count);
-
-// Write count bytes from buf. Return the number of bytes
-// written (count).
-ssize_t rd_write (const void* buf, size_t count);
-
-
-typedef struct {
-
- unsigned cylinders ;
- unsigned heads ;
- unsigned sectors ;
-
- //iso file descriptor
- int fd ;
-} device_image_t;
-
-
-
-struct controller_t {
- struct {
- rd_bool busy ;
- rd_bool drive_ready ;
- rd_bool write_fault ;
- rd_bool seek_complete ;
- rd_bool drq ;
- rd_bool corrected_data ;
- rd_bool index_pulse ;
- unsigned int index_pulse_count ;
- rd_bool err ;
- } status;
- Bit8u error_register ;
- Bit8u head_no ;
- union {
- Bit8u sector_count ;
- struct {
-#ifdef RD_LITTLE_ENDIAN
- unsigned c_d : 1;
- unsigned i_o : 1;
- unsigned rel : 1;
- unsigned tag : 5;
-
-#else /* RD_BIG_ENDIAN */
- unsigned tag : 5;
- unsigned rel : 1;
- unsigned i_o : 1;
- unsigned c_d : 1;
-#endif
-
- } interrupt_reason;
- };
- Bit8u sector_no ;
- union {
- Bit16u cylinder_no ;
- Bit16u byte_count ;
- };
- Bit8u buffer[2048]; ;
- Bit32u buffer_index ;
- Bit32u drq_index ;
- Bit8u current_command ;
- Bit8u sectors_per_block ;
- Bit8u lba_mode ;
- struct {
- // 0=normal, 1=reset controller
- rd_bool reset ;
- // 0=allow irq, 1=disable irq
- rd_bool disable_irq ;
- } control;
- Bit8u reset_in_progress ;
- Bit8u features ;
- };
-
-struct sense_info_t{
- sense_t sense_key ;
- struct {
- Bit8u arr[4] ;
- } information;
- struct {
- Bit8u arr[4] ;
- } specific_inf;
- struct {
- Bit8u arr[3] ;
- } key_spec;
- Bit8u fruc ;
- Bit8u asc ;
- Bit8u ascq ;
-};
-
-struct error_recovery_t {
- unsigned char data[8] ;
-
- // error_recovery_t ();
-};
-
-uint16 rd_read_16bit(const uint8* buf); //__attribute__(regparm(1))
-uint32 rd_read_32bit(const uint8* buf); //__attribute__(regparm(1))
-
-struct cdrom_t {
- rd_bool ready ;
- rd_bool locked ;
-
-
- struct cdrom_interface *cd ;
-
- uint32 capacity ;
- int next_lba ;
- int remaining_blocks ;
- struct currentStruct {
- struct error_recovery_t error_recovery ;
- } current;
-};
-
-struct atapi_t {
- uint8 command ;
- int drq_bytes ;
- int total_bytes_remaining ;
-};
-
-
-typedef enum {
- IDE_NONE, IDE_DISK, IDE_CDROM
-} device_type_t ;
-
-
- // FIXME:
- // For each ATA channel we should have one controller struct
- // and an array of two drive structs
-struct channel_t {
- struct drive_t {
- device_image_t hard_drive ;
- device_type_t device_type ;
- // 512 byte buffer for ID drive command
- // These words are stored in native word endian format, as
- // they are fetched and returned via a return(), so
- // there's no need to keep them in x86 endian format.
- Bit16u id_drive[256] ;
-
- struct controller_t controller ;
- struct cdrom_t cdrom ;
- struct sense_info_t sense ;
- struct atapi_t atapi ;
-
- Bit8u model_no[41] ;
- } drives[2];
- unsigned drive_select ;
-
- Bit16u ioaddr1 ;
- Bit16u ioaddr2 ;
- Bit8u irq ;
-};
-
-struct ramdisk_t;
-
-struct ramdisk_ctrl_ops {
- Bit32u (*init)(struct ramdisk_t *ramdisk,
- struct vm_device *dev);
- void (*close)(struct ramdisk_t *ramdisk);
- void (*reset)(struct ramdisk_t *ramdisk, unsigned type);
-
-};
-
-struct ramdisk_emu_ops {
-
- uint_t (*read_port)(ushort_t port,
- void *src,
- uint_t length,
- struct vm_device *dev);
-
- uint_t (*write_port)(ushort_t port,
- void *src,
- uint_t length,
- struct vm_device *dev);
-
- uint_t (*read_port_ignore)(ushort_t port,
- void *src,
- uint_t length,
- struct vm_device *dev);
-
- uint_t (*write_port_ignore)(ushort_t port,
- void *src,
- uint_t length,
- struct vm_device *dev);
-};
-
-
-struct ramdisk_t {
-
- struct channel_t channels[MAX_ATA_CHANNEL] ;
-
- struct ramdisk_ctrl_ops cops;
-
- struct ramdisk_emu_ops eops;
-
- void *private_data ;
- // struct vm_device *dev;
-};
-
-struct ramdisk_t * create_ramdisk(void);
+struct vm_device * create_ramdisk(void);
#endif
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#ifndef __SERIAL_H__
#define __SERIAL_H__
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __SIMPLE_PIC_H
#define __SIMPLE_PIC_H
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __TIMER_H
#define __TIMER_H
+++ /dev/null
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
-#ifndef __DEBUG_H
-#define __DEBUG_H
-
-#include <geekos/serial.h>
-#include <geekos/screen.h>
-
-
-
-
-void PrintBoth(const char * format, ...);
-
-
-
-#endif
+++ /dev/null
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
-#ifndef __NET_H__
-#define __NET_H__
-
-
-
-void Init_Network();
-
-
-void test_network();
-
-
-
-
-
-#endif
+++ /dev/null
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
-#ifndef GEEKOS_PCI_H
-#define GEEKOS_PCI_H
-
-#include <geekos/ktypes.h>
-
-int Init_PCI();
-
-#endif /* GEEKOS_PCI_H */
+++ /dev/null
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
-#ifndef __QUEUE_H__
-#define __QUEUE_H__
-
-#include <geekos/list2.h>
-#include <geekos/ktypes.h>
-#include <geekos/malloc.h>
-
-
-/* IMPORTANT:
- * This implementation currently does no locking, and as such is not
- * SMP/thread/interrupt safe
- */
-
-
-struct queue_entry {
- void * entry;
- struct list_head entry_list;
-};
-
-
-struct gen_queue {
- uint_t num_entries;
- struct list_head entries;
-
- // We really need to implement this....
- // void * lock;
-};
-
-
-struct gen_queue * create_queue();
-void init_queue(struct gen_queue * queue);
-
-void enqueue(struct gen_queue * queue, void * entry);
-void * dequeue(struct gen_queue * queue);
-
-
-
-
-#endif
+++ /dev/null
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
-#ifndef __RING_BUFFER_H__
-#define __RING_BUFFER_H__
-
-
-#include <geekos/ktypes.h>
-
-
-struct ring_buffer {
- uchar_t * buf;
- uint_t size;
-
- uint_t start;
- uint_t end;
- uint_t current_len;
-
-};
-
-
-void init_ring_buffer(struct ring_buffer * ring, uint_t size);
-struct ring_buffer * create_ring_buffer(uint_t size);
-
-void free_ring_buffer(struct ring_buffer * ring);
-
-
-int rb_read(struct ring_buffer * ring, char * dst, uint_t len);
-int rb_peek(struct ring_buffer * ring, char * dst, uint_t len);
-int rb_delete(struct ring_buffer * ring, uint_t len);
-int rb_write(struct ring_buffer * ring, char * src, uint_t len);
-int rb_data_len(struct ring_buffer * ring);
-int rb_capacity(struct ring_buffer * ring);
-
-
-void print_ring_buffer(struct ring_buffer * ring);
-
-
-#endif // ! __RING_BUFFER_H__
+++ /dev/null
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
-
-#ifndef SERIAL_H
-#define SERIAL_H
-
-#include <geekos/irq.h>
-#include <geekos/string.h>
-#include <geekos/io.h>
-#include <geekos/screen.h>
-
-#define COM1_IRQ 4
-#define DEFAULT_SERIAL_ADDR 0x3F8
-
-
-#ifndef SERIAL_PRINT_DEBUG_LEVEL
-#define SERIAL_PRINT_DEBUG_LEVEL 10
-#endif
-
-void SerialPutChar(unsigned char c);
-
-void SerialPrint(const char * format, ...);
-void SerialPrintLevel(int level, const char * format, ...);
-void SerialPrintList(const char * format, va_list ap);
-
-void SerialPutLine(char * line);
-void SerialPutLineN(char * line, int len);
-
-
-void SerialPrintHex(unsigned char x);
-void SerialMemDump(unsigned char *start, int n);
-
-void Init_Serial();
-void InitSerialAddr(unsigned short io_addr);
-
-#endif
+++ /dev/null
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
-#ifndef __VM_H
-#define __VM_H
-
-int RunVMM(struct Boot_Info * bootInfo);
-
-
-#endif
-
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __SVM_H
#define __SVM_H
-#include <palacios/vmm.h>
#ifdef __V3VEE__
+#include <palacios/vmm.h>
+
+
#include <palacios/vmcb.h>
#include <palacios/vmm_util.h>
#define SVM_HANDLER_ERROR 0x1
#define SVM_HANDLER_HALT 0x2
-#endif
void Init_SVM(struct vmm_ctrl_ops * vmm_ops);
int is_svm_capable();
+#endif
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __SVM_HALT_H
#define __SVM_HALT_H
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __SVM_HANDLER_H
#define __SVM_HANDLER_H
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __SVM_IO_H
#define __SVM_IO_H
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#ifndef __SVM_PAUSE_H
#define __SVM_PAUSE_H
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __SVM_WBINVD_H
#define __SVM_WBINVD_H
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VM_DEV_H
#define __VM_DEV_H
+#ifdef __V3VEE__
+
#include <palacios/vmm_types.h>
#include <palacios/vmm_list.h>
#include <palacios/vmm_dev_mgr.h>
int dev_unhook_irq(struct vm_device * dev, uint_t irq);
+
+#endif // ! __V3VEE__
+
#endif
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VM_GUEST_H
#define __VM_GUEST_H
void PrintV3CtrlRegs(struct guest_info * info);
void PrintV3GPRs(struct guest_info * info);
-#endif
+#endif // ! __V3VEE__
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VM_GUEST_MEM_H
#define __VM_GUEST_MEM_H
+
+#ifdef __V3VEE__
+
#include <palacios/vm_guest.h>
#include <palacios/vmm_mem.h>
// TODO int write_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, char * src);
-
+#endif // ! __V3VEE__
#endif
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VMCB_H
#define __VMCB_H
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-#ifndef __VMCS_H
-#define __VMCS_H
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ * Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+#ifndef __VMCS_H__
+#define __VMCS_H__
+
+#ifdef __V3VEE__
+
#include <palacios/vmm_types.h>
#include <palacios/vmcs_gen.h>
+#endif // ! __V3VEE__
+
+
#endif
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Automatically Generated File
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef __VMCS_GEN__
+#define __VMCS_GEN__
+
+#ifdef __V3VEE__
-#ifndef vmcs_gen
-#define vmcs_gen
#include <palacios/vmcs.h>
#include <palacios/vmm.h>
void PrintTrace_HOST_RIP();
void PrintTrace_VMCS_ALL();
+
+
+#endif // !__V3VEE
+
#endif
+
+
+
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VMM_H
#define __VMM_H
-#define PrintError(fmt, args...) \
- do { \
- extern struct vmm_os_hooks * os_hooks; \
- if ((os_hooks) && (os_hooks)->print_debug) { \
- (os_hooks)->print_debug((fmt), ##args); \
- } \
+#define PrintError(fmt, args...) \
+ do { \
+ extern struct vmm_os_hooks * os_hooks; \
+ if ((os_hooks) && (os_hooks)->print_debug) { \
+ (os_hooks)->print_debug("%s(%d): " fmt, __FILE__, __LINE__, ##args); \
+ } \
} while (0)
#if VMM_TRACE
-#define PrintTrace(fmt, args...) \
- do { \
- extern struct vmm_os_hooks * os_hooks; \
- if ((os_hooks) && (os_hooks)->print_trace) { \
- (os_hooks)->print_trace((fmt), ##args); \
- } \
+#define PrintTrace(fmt, args...) \
+ do { \
+ extern struct vmm_os_hooks * os_hooks; \
+ if ((os_hooks) && (os_hooks)->print_trace) { \
+ (os_hooks)->print_trace(fmt, ##args); \
+ } \
} while (0)
#else
#define PrintTrace(fmt, args...)
ret; \
}) \
+#define V3_Yield(addr) \
+ do { \
+ extern struct vmm_os_hooks * os_hooks; \
+ if ((os_hooks) && (os_hooks)->yield_cpu) { \
+ (os_hooks)->yield_cpu(); \
+ } \
+ } while (0) \
+
+
+
+
/* ** */
// This is the value given when the interrupt is hooked.
// This will never be NULL
- void *opaque;
+ void * opaque;
};
-void deliver_interrupt_to_vmm(struct vmm_intr_state *state);
+void deliver_interrupt_to_vmm(struct vmm_intr_state * state);
/* This will contain function pointers that provide OS services */
void (*start_kernel_thread)(); // include pointer to function
-
+ void (*yield_cpu)();
};
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VMM_CONFIG_H__
#define __VMM_CONFIG_H__
#ifdef __V3VEE__
+
#include <palacios/vm_guest.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VMM_CTRL_REGS_H
#define __VMM_CTRL_REGS_H
+#ifdef __V3VEE__
+
#include <palacios/vm_guest.h>
int handle_cr3_read(struct guest_info * info);
-#define CR3_32_SAME_BASE(source1,source2) ((source1)->pdt_base_addr == (source2)->pdt_base_addr)
-#define CR3_32_COPY_FLAGS(source,dest) do { (dest)->rsvd1=(source)->rsvd1; (dest)->pwt=(source)->pwt; (dest)->pcd=(source)->pcd; } while (0)
-#define CR3_32_COPY_BASE(source,dest) do { (dest)->pdt_base_addr = (source)->pdt_base_addr; } while (0)
+#endif // ! __V3VEE__
#endif
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#ifndef __VMM_DEBUG_H
#define __VMM_DEBUG_H
#ifdef __V3VEE__
+
#include <palacios/vmm.h>
struct dbg_bp32 {
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-#ifndef __VMM_EMULATE_H
-#define __VMM_EMULATE_H
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef __VMM_DECODER_H
+#define __VMM_DECODER_H
#ifdef __V3VEE__
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef _VMM_DEV_MGR
#define _VMM_DEV_MGR
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VMM_EMULATOR_H__
#define __VMM_EMULATOR_H__
-/* Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
+/*
+ Copyright (c) 2002, 2004, Christopher Clark
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the original author; nor the names of any contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
/* Modifications made by Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+
#ifndef __VMM_HASHTABLE_H__
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VMM_INTR_H_
#define __VMM_INTR_H_
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VMM_IO_H
#define __VMM_IO_H
+#ifdef __V3VEE__
#include <palacios/vmm_types.h>
#include <palacios/vmm_util.h>
-#ifdef __V3VEE__
struct vmm_io_hook;
void PrintDebugIOMap(struct vmm_io_map * io_map);
+
+
+void v3_outb(ushort_t port, uchar_t value);
+uchar_t v3_inb(ushort_t port);
+
+void v3_outw(ushort_t port, ushort_t value);
+ushort_t v3_inw(ushort_t port);
+
+void v3_outdw(ushort_t port, uint_t value);
+uint_t v3_indw(ushort_t port);
+
+
+
#endif // !__V3VEE__
/* Stolen From Linux list implementation */
-/* Modifications by Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/* 2008, Modifications by Jack Lange <jarusl@cs.northwestern.edu> */
+
#ifndef _VMM_LIST_H
#define _VMM_LIST_H
-// JRL FIXME
-// #ifdef __V3VEE__
+
+#ifdef __V3VEE__
#include <palacios/vmm_string.h>
pos = n)
-// JRL FIXME
-//#endif // ! __V3VEE__
+
+#endif // ! __V3VEE__
#endif
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#ifndef __VMM_MEM_H
#define __VMM_MEM_H
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#ifndef __VMM_PAGING_H
#define __VMM_PAGING_H
+#ifdef __V3VEE__
+
#include <palacios/vmm_types.h>
#include <palacios/vmm_util.h>
*/
-#ifdef __V3VEE__
+
#define MAX_PTE32_ENTRIES 1024
#define MAX_PDE32_ENTRIES 1024
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#ifndef __VMM_QUEUE_H__
#define __VMM_QUEUE_H__
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VMM_SHADOW_PAGING_H
#define __VMM_SHADOW_PAGING_H
--- /dev/null
+/* Copyright (C) 1989, 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* As a special exception, if you include this header file into source
+ files compiled by GCC, this header file does not by itself cause
+ the resulting executable to be covered by the GNU General Public
+ License. This exception does not however invalidate any other
+ reasons why the executable file might be covered by the GNU General
+ Public License. */
+
+/*
+ * ISO C Standard: 7.17 Common definitions <stddef.h>
+ */
+#if (!defined(_STDDEF_H) && !defined(_STDDEF_H_) && !defined(_ANSI_STDDEF_H) \
+ && !defined(__STDDEF_H__)) \
+ || defined(__need_wchar_t) || defined(__need_size_t) \
+ || defined(__need_ptrdiff_t) || defined(__need_NULL) \
+ || defined(__need_wint_t)
+
+/* Any one of these symbols __need_* means that GNU libc
+ wants us just to define one data type. So don't define
+ the symbols that indicate this file's entire job has been done. */
+#if (!defined(__need_wchar_t) && !defined(__need_size_t) \
+ && !defined(__need_ptrdiff_t) && !defined(__need_NULL) \
+ && !defined(__need_wint_t))
+#define _STDDEF_H
+#define _STDDEF_H_
+/* snaroff@next.com says the NeXT needs this. */
+#define _ANSI_STDDEF_H
+/* Irix 5.1 needs this. */
+#define __STDDEF_H__
+#endif
+
+#ifndef __sys_stdtypes_h
+/* This avoids lossage on SunOS but only if stdtypes.h comes first.
+ There's no way to win with the other order! Sun lossage. */
+
+/* On 4.3bsd-net2, make sure ansi.h is included, so we have
+ one less case to deal with in the following. */
+#if defined (__BSD_NET2__) || defined (____386BSD____) || (defined (__FreeBSD__) && (__FreeBSD__ < 5)) || defined(__NetBSD__)
+#include <machine/ansi.h>
+#endif
+/* On FreeBSD 5, machine/ansi.h does not exist anymore... */
+#if defined (__FreeBSD__) && (__FreeBSD__ >= 5)
+#include <sys/_types.h>
+#endif
+
+/* In 4.3bsd-net2, machine/ansi.h defines these symbols, which are
+ defined if the corresponding type is *not* defined.
+ FreeBSD-2.1 defines _MACHINE_ANSI_H_ instead of _ANSI_H_ */
+#if defined(_ANSI_H_) || defined(_MACHINE_ANSI_H_)
+#if !defined(_SIZE_T_) && !defined(_BSD_SIZE_T_)
+#define _SIZE_T
+#endif
+#if !defined(_PTRDIFF_T_) && !defined(_BSD_PTRDIFF_T_)
+#define _PTRDIFF_T
+#endif
+/* On BSD/386 1.1, at least, machine/ansi.h defines _BSD_WCHAR_T_
+ instead of _WCHAR_T_. */
+#if !defined(_WCHAR_T_) && !defined(_BSD_WCHAR_T_)
+#ifndef _BSD_WCHAR_T_
+#define _WCHAR_T
+#endif
+#endif
+/* Undef _FOO_T_ if we are supposed to define foo_t. */
+#if defined (__need_ptrdiff_t) || defined (_STDDEF_H_)
+#undef _PTRDIFF_T_
+#undef _BSD_PTRDIFF_T_
+#endif
+#if defined (__need_size_t) || defined (_STDDEF_H_)
+#undef _SIZE_T_
+#undef _BSD_SIZE_T_
+#endif
+#if defined (__need_wchar_t) || defined (_STDDEF_H_)
+#undef _WCHAR_T_
+#undef _BSD_WCHAR_T_
+#endif
+#endif /* defined(_ANSI_H_) || defined(_MACHINE_ANSI_H_) */
+
+/* Sequent's header files use _PTRDIFF_T_ in some conflicting way.
+ Just ignore it. */
+#if defined (__sequent__) && defined (_PTRDIFF_T_)
+#undef _PTRDIFF_T_
+#endif
+
+/* On VxWorks, <type/vxTypesBase.h> may have defined macros like
+ _TYPE_size_t which will typedef size_t. fixincludes patched the
+ vxTypesBase.h so that this macro is only defined if _GCC_SIZE_T is
+ not defined, and so that defining this macro defines _GCC_SIZE_T.
+ If we find that the macros are still defined at this point, we must
+ invoke them so that the type is defined as expected. */
+#if defined (_TYPE_ptrdiff_t) && (defined (__need_ptrdiff_t) || defined (_STDDEF_H_))
+_TYPE_ptrdiff_t;
+#undef _TYPE_ptrdiff_t
+#endif
+#if defined (_TYPE_size_t) && (defined (__need_size_t) || defined (_STDDEF_H_))
+_TYPE_size_t;
+#undef _TYPE_size_t
+#endif
+#if defined (_TYPE_wchar_t) && (defined (__need_wchar_t) || defined (_STDDEF_H_))
+_TYPE_wchar_t;
+#undef _TYPE_wchar_t
+#endif
+
+/* In case nobody has defined these types, but we aren't running under
+ GCC 2.00, make sure that __PTRDIFF_TYPE__, __SIZE_TYPE__, and
+ __WCHAR_TYPE__ have reasonable values. This can happen if the
+ parts of GCC is compiled by an older compiler, that actually
+ include gstddef.h, such as collect2. */
+
+/* Signed type of difference of two pointers. */
+
+/* Define this type if we are doing the whole job,
+ or if we want this type in particular. */
+#if defined (_STDDEF_H) || defined (__need_ptrdiff_t)
+#ifndef _PTRDIFF_T /* in case <sys/types.h> has defined it. */
+#ifndef _T_PTRDIFF_
+#ifndef _T_PTRDIFF
+#ifndef __PTRDIFF_T
+#ifndef _PTRDIFF_T_
+#ifndef _BSD_PTRDIFF_T_
+#ifndef ___int_ptrdiff_t_h
+#ifndef _GCC_PTRDIFF_T
+#define _PTRDIFF_T
+#define _T_PTRDIFF_
+#define _T_PTRDIFF
+#define __PTRDIFF_T
+#define _PTRDIFF_T_
+#define _BSD_PTRDIFF_T_
+#define ___int_ptrdiff_t_h
+#define _GCC_PTRDIFF_T
+#ifndef __PTRDIFF_TYPE__
+#define __PTRDIFF_TYPE__ long int
+#endif
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#endif /* _GCC_PTRDIFF_T */
+#endif /* ___int_ptrdiff_t_h */
+#endif /* _BSD_PTRDIFF_T_ */
+#endif /* _PTRDIFF_T_ */
+#endif /* __PTRDIFF_T */
+#endif /* _T_PTRDIFF */
+#endif /* _T_PTRDIFF_ */
+#endif /* _PTRDIFF_T */
+
+/* If this symbol has done its job, get rid of it. */
+#undef __need_ptrdiff_t
+
+#endif /* _STDDEF_H or __need_ptrdiff_t. */
+
+/* Unsigned type of `sizeof' something. */
+
+/* Define this type if we are doing the whole job,
+ or if we want this type in particular. */
+#if defined (_STDDEF_H) || defined (__need_size_t)
+#ifndef __size_t__ /* BeOS */
+#ifndef __SIZE_T__ /* Cray Unicos/Mk */
+#ifndef _SIZE_T /* in case <sys/types.h> has defined it. */
+#ifndef _SYS_SIZE_T_H
+#ifndef _T_SIZE_
+#ifndef _T_SIZE
+#ifndef __SIZE_T
+#ifndef _SIZE_T_
+#ifndef _BSD_SIZE_T_
+#ifndef _SIZE_T_DEFINED_
+#ifndef _SIZE_T_DEFINED
+#ifndef _BSD_SIZE_T_DEFINED_ /* Darwin */
+#ifndef _SIZE_T_DECLARED /* FreeBSD 5 */
+#ifndef ___int_size_t_h
+#ifndef _GCC_SIZE_T
+#ifndef _SIZET_
+#ifndef __size_t
+#define __size_t__ /* BeOS */
+#define __SIZE_T__ /* Cray Unicos/Mk */
+#define _SIZE_T
+#define _SYS_SIZE_T_H
+#define _T_SIZE_
+#define _T_SIZE
+#define __SIZE_T
+#define _SIZE_T_
+#define _BSD_SIZE_T_
+#define _SIZE_T_DEFINED_
+#define _SIZE_T_DEFINED
+#define _BSD_SIZE_T_DEFINED_ /* Darwin */
+#define _SIZE_T_DECLARED /* FreeBSD 5 */
+#define ___int_size_t_h
+#define _GCC_SIZE_T
+#define _SIZET_
+#if defined (__FreeBSD__) && (__FreeBSD__ >= 5)
+/* __size_t is a typedef on FreeBSD 5!, must not trash it. */
+#else
+#define __size_t
+#endif
+#ifndef __SIZE_TYPE__
+#define __SIZE_TYPE__ long unsigned int
+#endif
+#if !(defined (__GNUG__) && defined (size_t))
+typedef __SIZE_TYPE__ size_t;
+#ifdef __BEOS__
+typedef long ssize_t;
+#endif /* __BEOS__ */
+#endif /* !(defined (__GNUG__) && defined (size_t)) */
+#endif /* __size_t */
+#endif /* _SIZET_ */
+#endif /* _GCC_SIZE_T */
+#endif /* ___int_size_t_h */
+#endif /* _SIZE_T_DECLARED */
+#endif /* _BSD_SIZE_T_DEFINED_ */
+#endif /* _SIZE_T_DEFINED */
+#endif /* _SIZE_T_DEFINED_ */
+#endif /* _BSD_SIZE_T_ */
+#endif /* _SIZE_T_ */
+#endif /* __SIZE_T */
+#endif /* _T_SIZE */
+#endif /* _T_SIZE_ */
+#endif /* _SYS_SIZE_T_H */
+#endif /* _SIZE_T */
+#endif /* __SIZE_T__ */
+#endif /* __size_t__ */
+#undef __need_size_t
+#endif /* _STDDEF_H or __need_size_t. */
+
+
+/* Wide character type.
+ Locale-writers should change this as necessary to
+ be big enough to hold unique values not between 0 and 127,
+ and not (wchar_t) -1, for each defined multibyte character. */
+
+/* Define this type if we are doing the whole job,
+ or if we want this type in particular. */
+#if defined (_STDDEF_H) || defined (__need_wchar_t)
+#ifndef __wchar_t__ /* BeOS */
+#ifndef __WCHAR_T__ /* Cray Unicos/Mk */
+#ifndef _WCHAR_T
+#ifndef _T_WCHAR_
+#ifndef _T_WCHAR
+#ifndef __WCHAR_T
+#ifndef _WCHAR_T_
+#ifndef _BSD_WCHAR_T_
+#ifndef _BSD_WCHAR_T_DEFINED_ /* Darwin */
+#ifndef _BSD_RUNE_T_DEFINED_ /* Darwin */
+#ifndef _WCHAR_T_DECLARED /* FreeBSD 5 */
+#ifndef _WCHAR_T_DEFINED_
+#ifndef _WCHAR_T_DEFINED
+#ifndef _WCHAR_T_H
+#ifndef ___int_wchar_t_h
+#ifndef __INT_WCHAR_T_H
+#ifndef _GCC_WCHAR_T
+#define __wchar_t__ /* BeOS */
+#define __WCHAR_T__ /* Cray Unicos/Mk */
+#define _WCHAR_T
+#define _T_WCHAR_
+#define _T_WCHAR
+#define __WCHAR_T
+#define _WCHAR_T_
+#define _BSD_WCHAR_T_
+#define _WCHAR_T_DEFINED_
+#define _WCHAR_T_DEFINED
+#define _WCHAR_T_H
+#define ___int_wchar_t_h
+#define __INT_WCHAR_T_H
+#define _GCC_WCHAR_T
+#define _WCHAR_T_DECLARED
+
+/* On BSD/386 1.1, at least, machine/ansi.h defines _BSD_WCHAR_T_
+ instead of _WCHAR_T_, and _BSD_RUNE_T_ (which, unlike the other
+ symbols in the _FOO_T_ family, stays defined even after its
+ corresponding type is defined). If we define wchar_t, then we
+ must undef _WCHAR_T_; for BSD/386 1.1 (and perhaps others), if
+ we undef _WCHAR_T_, then we must also define rune_t, since
+ headers like runetype.h assume that if machine/ansi.h is included,
+ and _BSD_WCHAR_T_ is not defined, then rune_t is available.
+ machine/ansi.h says, "Note that _WCHAR_T_ and _RUNE_T_ must be of
+ the same type." */
+#ifdef _BSD_WCHAR_T_
+#undef _BSD_WCHAR_T_
+#ifdef _BSD_RUNE_T_
+#if !defined (_ANSI_SOURCE) && !defined (_POSIX_SOURCE)
+typedef _BSD_RUNE_T_ rune_t;
+#define _BSD_WCHAR_T_DEFINED_
+#define _BSD_RUNE_T_DEFINED_ /* Darwin */
+#if defined (__FreeBSD__) && (__FreeBSD__ < 5)
+/* Why is this file so hard to maintain properly? In constrast to
+ the comment above regarding BSD/386 1.1, on FreeBSD for as long
+ as the symbol has existed, _BSD_RUNE_T_ must not stay defined or
+ redundant typedefs will occur when stdlib.h is included after this file. */
+#undef _BSD_RUNE_T_
+#endif
+#endif
+#endif
+#endif
+/* FreeBSD 5 can't be handled well using "traditional" logic above
+ since it no longer defines _BSD_RUNE_T_ yet still desires to export
+ rune_t in some cases... */
+#if defined (__FreeBSD__) && (__FreeBSD__ >= 5)
+#if !defined (_ANSI_SOURCE) && !defined (_POSIX_SOURCE)
+#if __BSD_VISIBLE
+#ifndef _RUNE_T_DECLARED
+typedef __rune_t rune_t;
+#define _RUNE_T_DECLARED
+#endif
+#endif
+#endif
+#endif
+
+#ifndef __WCHAR_TYPE__
+#define __WCHAR_TYPE__ int
+#endif
+#ifndef __cplusplus
+typedef __WCHAR_TYPE__ wchar_t;
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif /* _WCHAR_T_DECLARED */
+#endif /* _BSD_RUNE_T_DEFINED_ */
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif /* __WCHAR_T__ */
+#endif /* __wchar_t__ */
+#undef __need_wchar_t
+#endif /* _STDDEF_H or __need_wchar_t. */
+
+#if defined (__need_wint_t)
+#ifndef _WINT_T
+#define _WINT_T
+
+#ifndef __WINT_TYPE__
+#define __WINT_TYPE__ unsigned int
+#endif
+typedef __WINT_TYPE__ wint_t;
+#endif
+#undef __need_wint_t
+#endif
+
+/* In 4.3bsd-net2, leave these undefined to indicate that size_t, etc.
+ are already defined. */
+/* BSD/OS 3.1 and FreeBSD [23].x require the MACHINE_ANSI_H check here. */
+#if defined(_ANSI_H_) || defined(_MACHINE_ANSI_H_)
+/* The references to _GCC_PTRDIFF_T_, _GCC_SIZE_T_, and _GCC_WCHAR_T_
+ are probably typos and should be removed before 2.8 is released. */
+#ifdef _GCC_PTRDIFF_T_
+#undef _PTRDIFF_T_
+#undef _BSD_PTRDIFF_T_
+#endif
+#ifdef _GCC_SIZE_T_
+#undef _SIZE_T_
+#undef _BSD_SIZE_T_
+#endif
+#ifdef _GCC_WCHAR_T_
+#undef _WCHAR_T_
+#undef _BSD_WCHAR_T_
+#endif
+/* The following ones are the real ones. */
+#ifdef _GCC_PTRDIFF_T
+#undef _PTRDIFF_T_
+#undef _BSD_PTRDIFF_T_
+#endif
+#ifdef _GCC_SIZE_T
+#undef _SIZE_T_
+#undef _BSD_SIZE_T_
+#endif
+#ifdef _GCC_WCHAR_T
+#undef _WCHAR_T_
+#undef _BSD_WCHAR_T_
+#endif
+#endif /* _ANSI_H_ || _MACHINE_ANSI_H_ */
+
+#endif /* __sys_stdtypes_h */
+
+/* A null pointer constant. */
+
+#if defined (_STDDEF_H) || defined (__need_NULL)
+#undef NULL /* in case <stdio.h> has defined it. */
+#ifdef __GNUG__
+#define NULL __null
+#else /* G++ */
+#ifndef __cplusplus
+#define NULL ((void *)0)
+#else /* C++ */
+#define NULL 0
+#endif /* C++ */
+#endif /* G++ */
+#endif /* NULL not defined and <stddef.h> or need NULL. */
+#undef __need_NULL
+
+#ifdef _STDDEF_H
+
+/* Offset of member MEMBER in a struct of type TYPE. */
+#ifndef __cplusplus
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#else
+/* The cast to "char &" below avoids problems with user-defined
+ "operator &", which can appear in a POD type. */
+#define offsetof(TYPE, MEMBER) \
+ (__offsetof__ (reinterpret_cast <size_t> \
+ (&reinterpret_cast <const volatile char &> \
+ (static_cast<TYPE *> (0)->MEMBER))))
+#endif /* C++ */
+#endif /* _STDDEF_H was defined this time */
+
+#endif /* !_STDDEF_H && !_STDDEF_H_ && !_ANSI_STDDEF_H && !__STDDEF_H__
+ || __need_XXX was not defined before */
/* * String library
* Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
- * (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * (c) 2008, Lei Xia <xiaxlei@gmail.com>
- * (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * $Revision: 1.2 $
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "COPYING".
+ * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#ifndef STRING_H
-#define STRING_H
+/* Modifications:
+ * 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * 2008, Lei Xia <xiaxlei@gmail.com>
+ */
+
+#ifndef __VMM_STRING_H__
+#define __VMM_STRING_H__
#ifdef __V3VEE__
-#include <stddef.h>
+#include <palacios/vmm_stddef.h>
+
void* memset(void* s, int c, size_t n);
void* memcpy(void *dst, const void* src, size_t n);
int strcmp(const char* s1, const char* s2);
int strncmp(const char* s1, const char* s2, size_t limit);
char *strcat(char *s1, const char *s2);
+char *strncat(char *s1, const char *s2, size_t limit);
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t limit);
char *strdup(const char *s1);
double ceil(double x);
+
#endif // !__V3VEE__
#endif /* STRING_H */
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VMM_TIME_H
#define __VMM_TIME_H
+#ifdef __V3VEE__
#include <palacios/vmm_types.h>
#include <palacios/vmm_list.h>
};
-#ifdef __V3VEE__
+
struct vm_timer_ops {
void (*update_time)(ullong_t cpu_cycles, ullong_t cpu_freq, void * priv_data);
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VMM_TYPES_H
#define __VMM_TYPES_H
-#include <geekos/ktypes.h>
+#ifdef __V3VEE__
+#include <palacios/vmm_stddef.h>
+
-/*
typedef signed char schar_t;
typedef unsigned char uchar_t;
typedef signed long slong_t;
typedef unsigned long ulong_t;
-typedef unsigned long size_t;
-
-*/
+//typedef unsigned long size_t;
+
+#define false 0
+#define true 1
+typedef uchar_t bool;
typedef unsigned int uint32_t;
typedef int sint32_t;
+
+typedef unsigned short uint16_t;
+typedef short sint16_t;
+
+typedef unsigned char uint8_t;
+typedef char sint8_t;
+
typedef ulong_t addr_t;
+#endif // ! __V3VEE__
+
#endif
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VMM_UTIL_H
#define __VMM_UTIL_H
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifndef __VMM_XED_H__
#define __VMM_XED_H__
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#ifndef __VMX_H
#define __VMX_H
+#ifdef __V3VEE__
+
#include <palacios/vmm_types.h>
#include <palacios/vmcs.h>
int Do_VMM(struct VMXRegs regs);
-
+#endif // ! __V3VEE__
#endif
--- /dev/null
+#ifndef __V3_XED_COMPAT_H__
+#define __V3_XED_COMPAT_H__
+
+#include <palacios/vmm_stddef.h>
+
+
+/* Definition of the control structure for streams
+*/
+typedef struct file_struct {
+ short level; /* fill/empty level of buffer */
+ unsigned flags; /* File status flags */
+ char fd; /* File descriptor */
+ unsigned char hold; /* Ungetc char if no buffer */
+ short bsize; /* Buffer size */
+ unsigned char *buffer; /* Data transfer buffer */
+ unsigned char *curp; /* Current active pointer */
+ unsigned istemp; /* Temporary file indicator */
+ short token; /* Used for validity checking */
+} FILE;
+
+
+
+int fprintf(FILE *file, char *fmt, ...);
+int printf(char *fmt, ...);
+int fflush(FILE *stream);
+void abort(void);
+
+
+#endif
#include <xed/xed-common-hdrs.h>
-typedef unsigned char uint8_t;
-typedef unsigned short int uint16_t;
+ //typedef unsigned char uint8_t;
+//typedef unsigned short int uint16_t;
//typedef unsigned int uint32_t;
//typedef unsigned long int uint64_t;
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <devices/8237_dma.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <devices/8254.h>
#include <palacios/vmm.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#include <devices/8259a.h>
#include <palacios/vmm_intr.h>
/*
- * Zheng Cui
- * cuizheng@cs.unm.edu
- * July 2008
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Zheng Cui <cuizheng@cs.unm.edu>
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Zheng Cui <cuizheng@cs.unm.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
-
#include <devices/cdrom.h>
#include <palacios/vmm.h>
#endif
-extern ulong_t g_ramdiskImage;
-extern ulong_t s_ramdiskSize;
+
+ulong_t g_ramdiskImage;
+ulong_t s_ramdiskSize;
static
void cdrom_init(struct cdrom_interface * cdrom)
Ramdisk_Print_CD("[cdrom_init]\n");
V3_ASSERT(g_ramdiskImage);
cdrom->fd = g_ramdiskImage;
+ PrintDebug("CDIMAGE located at: %x\n", cdrom->fd);
cdrom->capacity_B = s_ramdiskSize;
//FIXME:lba
cdrom->lba = 1;
* Read CD TOC. Returns false if start track is out of bounds.
*/
static
-rd_bool cdrom_read_toc(struct cdrom_interface *cdrom, uint8* buf, int* length, rd_bool msf, int start_track)
+rd_bool cdrom_read_toc(struct cdrom_interface *cdrom, uint8_t* buf, int* length, rd_bool msf, int start_track)
{
Ramdisk_Print_CD("[cdrom_read_toc]\n");
return 1;
* Return CD-ROM capacity (in 2048 byte frames)
*/
static
-uint32 cdrom_capacity(struct cdrom_interface *cdrom)
+uint32_t cdrom_capacity(struct cdrom_interface *cdrom)
{
Ramdisk_Print_CD("[cdrom_capacity] s_ramdiskSize = %d\n", cdrom->capacity_B);
if (cdrom->lba) {
* Read a single block from the CD
*/
static
-void cdrom_read_block(struct cdrom_interface *cdrom, uint8* buf, int lba)// __attribute__(regparm(2));
+void cdrom_read_block(struct cdrom_interface *cdrom, uint8_t* buf, int lba)// __attribute__(regparm(2));
{
V3_ASSERT(lba != 0);
-
- Ramdisk_Print_CD("[cdrom_read_block] lba = %d\n", lba);
- memcpy(buf, (uint8 *)(cdrom->fd + lba*2048), 2048);
+
+ Ramdisk_Print_CD("[cdrom_read_block] lba = %d (cdrom_image_start=%x)\n", lba, cdrom->fd);
+ memcpy(buf, (uint8_t *)(cdrom->fd + lba * 2048), 2048);
+ PrintDebug("Returning from read block\n");
return;
}
return;
}
+
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ * Contributor: 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <devices/generic.h>
#include <palacios/vmm.h>
#include <palacios/vmm_types.h>
-#include <geekos/io.h>
+#include <palacios/vmm_list.h>
#define MEM_HOOKS 0 // not yet implmented in device model
#define IRQ_HOOKS 0 // not yet implemented in device model
+
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;
+ struct list_head port_list;
+ uint_t num_port_ranges;
+ struct list_head mem_list;
+ uint_t num_mem_ranges;
+ struct list_head irq_list;
+ uint_t num_irq_ranges;
};
-
-#ifdef RAMDISK_BOOT
-#include <devices/ramdisk.h>
-//ramdisk_state
-static struct ramdisk_t *ramdisk_state;
-#endif
+struct port_range {
+ uint_t start;
+ uint_t end;
+ uint_t type;
+ struct list_head range_link;
+};
+
+struct mem_range {
+ void * start;
+ void * end;
+ uint_t type;
+ struct list_head range_link;
+};
+struct irq_range {
+ uint_t start;
+ uint_t end;
+ uint_t type;
+ struct list_head range_link;
+};
-int generic_start_device(struct vm_device *dev)
+int generic_start_device(struct vm_device * dev)
{
PrintDebug("generic: start device\n");
return 0;
}
-int generic_stop_device(struct vm_device *dev)
+int generic_stop_device(struct vm_device * dev)
{
PrintDebug("generic: stop device\n");
return 0;
PrintDebug(" to port 0x%x ... ", port);
-#ifdef RAMDISK_BOOT
-
- uint_t err;
-
- if (((port >= 0x170 && port <= 0x177) || port == 0x376 || port == 0x377)
- && (dev->vm->cpu_mode == REAL)) {
-
-
- err = ramdisk_state->eops.write_port(port, src, length, dev);
-
- }else{
-#endif
switch (length) {
case 1:
- Out_Byte(port,((uchar_t*)src)[0]);
+ v3_outb(port,((uchar_t*)src)[0]);
break;
case 2:
- Out_Word(port,((ushort_t*)src)[0]);
+ v3_outw(port,((ushort_t*)src)[0]);
break;
case 4:
- Out_DWord(port,((uint_t*)src)[0]);
+ v3_outdw(port,((uint_t*)src)[0]);
break;
default:
for (i = 0; i < length; i++) {
- Out_Byte(port, ((uchar_t*)src)[i]);
+ v3_outb(port, ((uchar_t*)src)[i]);
}
} //switch length
-#ifdef RAMDISK_BOOT
- }//else not ramdisk
-#endif
+
+
PrintDebug(" done\n");
return length;
PrintDebug("generic: reading 0x%x bytes from port 0x%x ...", length, port);
-#ifdef RAMDISK_BOOT
-
- uint_t err;
-
- if (((port >= 0x170 && port <= 0x177) || port == 0x376 || port == 0x377)
- && (dev->vm->cpu_mode == REAL)) {
-
- err = ramdisk_state->eops.read_port(port, src, length, dev);
-
- }else{
-#endif
switch (length) {
case 1:
- ((uchar_t*)src)[0] = In_Byte(port);
+ ((uchar_t*)src)[0] = v3_inb(port);
break;
case 2:
- ((ushort_t*)src)[0] = In_Word(port);
+ ((ushort_t*)src)[0] = v3_inw(port);
break;
case 4:
- ((uint_t*)src)[0] = In_DWord(port);
+ ((uint_t*)src)[0] = v3_indw(port);
break;
default:
for (i = 0; i < length; i++) {
- ((uchar_t*)src)[i] = In_Byte(port);
+ ((uchar_t*)src)[i] = v3_inb(port);
}
}//switch length
-#ifdef RAMDISK_BOOT
- }//else not ramdisk
-#endif
PrintDebug(" done ... read 0x");
PrintDebug("%x", ((uchar_t*)src)[i]);
}
- PrintDebug(" to port 0x%x ... ", port);
-
- PrintDebug(" ignored\n");
-
-#ifdef RAMDISK_BOOT
-
- uint_t err;
-
- if (((port >= 0x3e8 && port <= 0x3ef) ||
- (port >= 0x2e8 && port <= 0x2ef))
- && (dev->vm->cpu_mode == REAL)) {
-
- err = ramdisk_state->eops.write_port_ignore(port, src, length, dev);
- }
-#endif
+ PrintDebug(" to port 0x%x ... ignored\n", port);
return length;
}
PrintDebug("generic: reading 0x%x bytes from port 0x%x ...", length, port);
- memset((char*)src,0,length);
+ memset((char*)src, 0, length);
PrintDebug(" ignored (return zeroed buffer)\n");
-#ifdef RAMDISK_BOOT
-
- uint_t err;
-
- if (((port >= 0x3e8 && port <= 0x3ef) ||
- (port >= 0x2e8 && port <= 0x2ef))
- && (dev->vm->cpu_mode == REAL)) {
-
- err = ramdisk_state->eops.read_port_ignore(port, src, length, dev);
- }
-#endif
-
return length;
}
-int generic_interrupt(uint_t irq,
- struct vm_device * dev)
-{
+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);
return 0;
-
}
-int generic_init_device(struct vm_device * dev)
-{
- struct generic_internal *state = (struct generic_internal *)(dev->private_data);
- uint_t i, j;
+int generic_init_device(struct vm_device * dev) {
+ struct generic_internal * state = (struct generic_internal *)(dev->private_data);
PrintDebug("generic: init_device\n");
-
- // Would read state here
-
generic_reset_device(dev);
- for (i = 0; i < state->num_port_ranges; i++) {
- PrintDebug("generic: hooking ports 0x%x to 0x%x as %x\n", state->port_ranges[i][0], state->port_ranges[i][1], state->port_ranges[i][2]==GENERIC_PRINT_AND_PASSTHROUGH ? "print-and-passthrough" : "print-and-ignore");
-#if PORT_HOOKS
- for (j = state->port_ranges[i][0]; j <= state->port_ranges[i][1]; j++) {
- if (state->port_ranges[i][2]==GENERIC_PRINT_AND_PASSTHROUGH) {
- if (dev_hook_io(dev, j, &generic_read_port_passthrough, &generic_write_port_passthrough)) {
- PrintDebug("generic: can't hook port 0x%x (already hooked?)\n", j);
- }
- } else if (state->port_ranges[i][2]==GENERIC_PRINT_AND_IGNORE) {
- if (dev_hook_io(dev, j, &generic_read_port_ignore, &generic_write_port_ignore)) {
- PrintDebug("generic: can't hook port 0x%x (already hooked?)\n", j);
- }
- }
+ if (PORT_HOOKS) { // This is a runtime conditional on a #define
+ struct port_range * tmp = NULL;
+
+ list_for_each_entry(tmp, &(state->port_list), range_link) {
+ uint_t i = 0;
+
+ PrintDebug("generic: hooking ports 0x%x to 0x%x as %x\n",
+ tmp->start, tmp->end,
+ (tmp->type == GENERIC_PRINT_AND_PASSTHROUGH) ? "print-and-passthrough" : "print-and-ignore");
+
+ for (i = tmp->start; i <= tmp->end; i++) {
+ if (tmp->type == GENERIC_PRINT_AND_PASSTHROUGH) {
+
+ if (dev_hook_io(dev, i, &generic_read_port_passthrough, &generic_write_port_passthrough)) {
+ PrintDebug("generic: can't hook port 0x%x (already hooked?)\n", i);
+ }
+
+ } else if (tmp->type == GENERIC_PRINT_AND_IGNORE) {
+
+ if (dev_hook_io(dev, i, &generic_read_port_ignore, &generic_write_port_ignore)) {
+ PrintDebug("generic: can't hook port 0x%x (already hooked?)\n", i);
+ }
+ }
+ }
+
}
-#else
+ } else {
PrintDebug("generic: hooking ports not supported\n");
-#endif
-
}
- for (i = 0; i < state->num_address_ranges; i++) {
- PrintDebug("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])) {
- PrintDebug("generic: Can't hook addresses 0x%x to 0x%x (already hooked?)\n",
- state->address_ranges[i][0], state->address_ranges[i][1]);
+
+ if (MEM_HOOKS) { // This is a runtime conditional on a #define
+ struct mem_range * tmp;
+
+ list_for_each_entry(tmp, &(state->mem_list), range_link) {
+
+ PrintDebug("generic: hooking addresses 0x%x to 0x%x\n",
+ tmp->start, tmp->end);
+
+
+ if (dev_hook_mem(dev, tmp->start, tmp->end)) {
+ PrintDebug("generic: Can't hook addresses 0x%x to 0x%x (already hooked?)\n",
+ tmp->start, tmp->end);
+ }
}
-#else
+ } else {
PrintDebug("generic: hooking addresses not supported\n");
-#endif
-
}
- for (i = 0; i < state->num_irq_ranges; i++) {
- PrintDebug("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)) {
- PrintDebug("generic: can't hook irq 0x%x (already hooked?)\n", j);
+
+
+ if (IRQ_HOOKS) { // This is a runtime conditional on a #define
+ struct irq_range * tmp;
+
+ list_for_each_entry(tmp, &(state->irq_list), range_link) {
+ uint_t i;
+
+ PrintDebug("generic: hooking irqs 0x%x to 0x%x\n",
+ tmp->start, tmp->end);
+
+ for (i = tmp->start; i <= tmp->end; i++) {
+ if (dev_hook_irq(dev, i, &generic_interrupt)) {
+ PrintDebug("generic: can't hook irq 0x%x (already hooked?)\n", i);
+ }
}
+
}
-#else
+ } else {
PrintDebug("generic: hooking irqs not supported\n");
-#endif
-
}
-#ifdef RAMDISK_BOOT
-
- ramdisk_state->cops.init(ramdisk_state, dev);
-#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;
+int generic_deinit_device(struct vm_device * dev) {
+ struct generic_internal * state = (struct generic_internal *)(dev->private_data);
+
PrintDebug("generic: deinit_device\n");
-#ifdef RAMDISK_BOOT
- ramdisk_state->cops.close(ramdisk_state);
-
-#endif
+ if (IRQ_HOOKS) { // This is a runtime conditional on a #define
+ struct irq_range * tmp;
+ struct irq_range * cur;
+
+ list_for_each_entry_safe(cur, tmp, &(state->irq_list), range_link) {
+ uint_t i;
- for (i = 0; i < state->num_irq_ranges; i++) {
- PrintDebug("generic: unhooking irqs 0x%x to 0x%x\n", state->irq_ranges[i][0], state->irq_ranges[i][1]);
+ PrintDebug("generic: unhooking irqs 0x%x to 0x%x\n",
+ cur->start, cur->end);
+
-#if IRQ_HOOKS
- for (j = state->irq_ranges[i][0]; j <= state->irq_ranges[i][1]; j++) {
- if (dev_unhook_irq(dev, j)) {
- PrintDebug("generic: can't unhook irq 0x%x (already unhooked?)\n",j);
+ for (i = cur->start; i <= cur->end; i++) {
+ if (dev_unhook_irq(dev, i)) {
+ PrintDebug("generic: can't unhook irq 0x%x (already unhooked?)\n", i);
+ }
}
+
+ list_del(&(cur->range_link));
+ state->num_irq_ranges--;
+ V3_Free(cur);
}
-#else
+ } else {
PrintDebug("generic: unhooking irqs not supported\n");
-#endif
-
}
- for (i = 0; i < state->num_address_ranges; i++) {
- PrintDebug("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])) {
- PrintDebug("generic: Can't unhook addresses 0x%x to 0x%x (already unhooked?)\n",
- state->address_ranges[i][0], state->address_ranges[i][1]);
+ if (MEM_HOOKS) {
+ struct mem_range * tmp;
+ struct mem_range * cur;
+
+ list_for_each_entry_safe(cur, tmp, &(state->mem_list), range_link) {
+
+ PrintDebug("generic: unhooking addresses 0x%x to 0x%x\n",
+ cur->start, cur->end);
+
+ if (dev_unhook_mem(dev, cur->start, cur->end)) {
+ PrintDebug("generic: Can't unhook addresses 0x%x to 0x%x (already unhooked?)\n",
+ cur->start, cur->end);
+ }
+
+ list_del(&(cur->range_link));
+ state->num_mem_ranges--;
+ V3_Free(cur);
}
-#else
+ } else {
PrintDebug("generic: unhooking addresses not supported\n");
-#endif
-
}
+
- for (i = 0; i < state->num_port_ranges; i++) {
- PrintDebug("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)) {
- PrintDebug("generic: can't unhook port 0x%x (already unhooked?)\n", j);
+ if (PORT_HOOKS) {
+ struct port_range * tmp;
+ struct port_range * cur;
+
+ list_for_each_entry_safe(cur, tmp, &(state->port_list), range_link) {
+ uint_t i;
+
+ PrintDebug("generic: unhooking ports 0x%x to 0x%x\n",
+ cur->start, cur->end);
+
+ for (i = cur->start; i <= cur->end; i++) {
+ if (dev_unhook_io(dev, i)) {
+ PrintDebug("generic: can't unhook port 0x%x (already unhooked?)\n", i);
+ }
}
+
+ list_del(&(cur->range_link));
+ state->num_port_ranges--;
+ V3_Free(cur);
}
-#else
+ } else {
PrintDebug("generic: unhooking ports not supported\n");
-#endif
-
}
+
+
generic_reset_device(dev);
return 0;
}
-struct vm_device *create_generic(generic_port_range_type port_ranges[],
- generic_address_range_type address_ranges[],
- generic_irq_range_type irq_ranges[])
-{
- struct generic_internal * generic_state = (struct generic_internal *)V3_Malloc(sizeof(struct generic_internal));
- int i;
- uint_t num_port_ranges, num_address_ranges, num_irq_ranges;
-
- num_port_ranges=0;
- if (port_ranges!=NULL) {
- i=0;
- while (port_ranges[i]!=NULL &&
- !(port_ranges[i][0]==0 && port_ranges[i][1]==0 && port_ranges[i][2]==0))
- { num_port_ranges++; i++; }
- }
+int v3_generic_add_port_range(struct vm_device * dev, uint_t start, uint_t end, uint_t type) {
-
- num_address_ranges=0;
- if (address_ranges!=NULL) {
- i=0;
- while (address_ranges[i]!=NULL &&
- !(address_ranges[i][0]==0 && address_ranges[i][1]==0 && address_ranges[i][2]==0))
- { num_address_ranges++; i++; }
- }
+ if (PORT_HOOKS) {
+ struct generic_internal * state = (struct generic_internal *)(dev->private_data);
- num_irq_ranges=0;
- if (irq_ranges!=NULL) {
- i=0;
- while (irq_ranges[i]!=NULL &&
- !(irq_ranges[i][0]==0 && irq_ranges[i][1]==0 && irq_ranges[i][2]==0) )
- { num_irq_ranges++; i++; }
- }
+ struct port_range * range = (struct port_range *)V3_Malloc(sizeof(struct port_range));
+ range->start = start;
+ range->end = end;
+ range->type = type;
-
- generic_state->num_port_ranges = num_port_ranges;
-
- if (num_port_ranges > 0) {
- generic_state->port_ranges = V3_Malloc(sizeof(generic_address_range_type) * num_port_ranges);
- memcpy(generic_state->port_ranges, port_ranges, sizeof(generic_port_range_type) * num_port_ranges);
+
+ PrintDebug("generic: Adding Port Range: 0x%x to 0x%x as %x\n",
+ range->start, range->end,
+ (range->type == GENERIC_PRINT_AND_PASSTHROUGH) ? "print-and-passthrough" : "print-and-ignore");
+
+ list_add(&(range->range_link), &(state->port_list));
+ state->num_port_ranges++;
} else {
- generic_state->port_ranges = NULL;
+ PrintDebug("generic: hooking IO ports not supported\n");
+ return -1;
}
+ return 0;
+}
- generic_state->num_address_ranges = num_address_ranges;
+int v3_generic_add_mem_range(struct vm_device * dev, void * start, void * end, uint_t type) {
- if (num_address_ranges > 0) {
- generic_state->address_ranges = V3_Malloc(sizeof(generic_address_range_type) * num_address_ranges);
- memcpy(generic_state->address_ranges, address_ranges, sizeof(generic_address_range_type) * num_address_ranges);
+ if (MEM_HOOKS) {
+ struct generic_internal * state = (struct generic_internal *)(dev->private_data);
+
+ struct mem_range * range = (struct mem_range *)V3_Malloc(sizeof(struct mem_range));
+ range->start = start;
+ range->end = end;
+ range->type = type;
+
+ list_add(&(range->range_link), &(state->port_list));
+ state->num_mem_ranges++;
} else {
- generic_state->address_ranges = NULL;
+ PrintDebug("generic: hooking memory not supported\n");
+ return -1;
}
+ return 0;
+}
- generic_state->num_irq_ranges = num_irq_ranges;
- if (num_irq_ranges > 0) {
- generic_state->irq_ranges = V3_Malloc(sizeof(generic_address_range_type) * num_irq_ranges);
- memcpy(generic_state->irq_ranges, irq_ranges, sizeof(generic_irq_range_type) * num_port_ranges);
+int v3_generic_add_irq_range(struct vm_device * dev, uint_t start, uint_t end, uint_t type) {
+
+ if (IRQ_HOOKS) {
+ struct generic_internal * state = (struct generic_internal *)(dev->private_data);
+
+ struct irq_range * range = (struct irq_range *)V3_Malloc(sizeof(struct irq_range));
+ range->start = start;
+ range->end = end;
+ range->type = type;
+
+ list_add(&(range->range_link), &(state->port_list));
+ state->num_irq_ranges++;
} else {
- generic_state->irq_ranges = NULL;
+ PrintDebug("generic: hooking IRQs not supported\n");
+ return -1;
}
-#ifdef RAMDISK_BOOT
+ return 0;
+}
- ramdisk_state = create_ramdisk();
- V3_ASSERT(ramdisk_state != NULL);
-#endif
- struct vm_device *device = create_device("GENERIC", &dev_ops, generic_state);
+struct vm_device * create_generic() {
+ struct generic_internal * generic_state = (struct generic_internal *)V3_Malloc(sizeof(struct generic_internal));
+
+ generic_state->num_port_ranges = 0;
+ generic_state->num_mem_ranges = 0;
+ generic_state->num_irq_ranges = 0;
+
+ INIT_LIST_HEAD(&(generic_state->port_list));
+ INIT_LIST_HEAD(&(generic_state->mem_list));
+ INIT_LIST_HEAD(&(generic_state->irq_list));
+
+ struct vm_device * device = create_device("GENERIC", &dev_ops, generic_state);
return device;
}
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <devices/keyboard.h>
-#include <geekos/io.h>
#include <palacios/vmm.h>
#include <palacios/vmm_types.h>
{
if (length == 1) {
- *((uchar_t*)dest) = In_Byte(port);
+ *((uchar_t*)dest) = v3_inb(port);
PrintDebug("keyboard: read of 0x%x from 80h\n", *((uchar_t*)dest));
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#include <devices/nvram.h>
#include <palacios/vmm.h>
struct vm_device * thedev = NULL;
+/*JRL: A hack and a fatal bug
static struct vm_device * demultiplex_timer_interrupt(uint_t period_us)
{
// hack
return thedev;
}
-
+*/
+/* JRL: Doesn't work
struct bcd_num {
uchar_t bot : 4;
uchar_t top : 4;
}
}
+*/
-
-
+/* JRL: This is completely broken...
void deliver_timer_interrupt_to_vmm(uint_t period_us)
{
struct vm_device * dev = demultiplex_timer_interrupt(period_us);
}
}
-
+*/
static int set_nvram_defaults(struct vm_device * dev)
{
-/*
- * Zheng Cui
- * cuizheng@cs.unm.edu
- * July 2008
+/*
+ *
+ * Copyright (C) 2002 MandrakeSoft S.A.
+ *
+ * MandrakeSoft S.A.
+ * 43, rue d'Aboukir
+ * 75002 Paris - France
+ * http://www.linux-mandrake.com/
+ * http://www.mandrakesoft.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Major modifications made for the V3VEE project
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Zheng Cui <cuizheng@cs.unm.edu>
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved for original changes
+ *
*/
+
#include <devices/ramdisk.h>
#include <palacios/vmm.h>
-#include <string.h>
+#include <devices/cdrom.h>
+#include <devices/ide.h>
-#ifdef DEBUG_RAMDISK
-#define Ramdisk_Print(_f, _a...) PrintTrace("\nramdisk.c(%d) " _f, __LINE__, ## _a)
-#else
-#define Ramdisk_Print(_f, _a...)
+
+#ifndef DEBUG_RAMDISK
+#undef PrintDebug
+#define PrintDebug(_f, _a...)
#endif
+
+
+/*
+ * Data type definitions
+ *
+ */
+#define INDEX_PULSE_CYCLE 10
+
+
+
+
+#define INTR_REASON_BIT_ERR 0x01
+#define UNABLE_FIND_TAT_CHANNEL_ERR 0x02
+#define DRQ_ERR 0x03
+#define READ_BUF_GT_512 0x04
+
+
+
+#define PRI_DATA_PORT 0x1f0
+#define PRI_FEATURES_PORT 0x1f1
+#define PRI_SECT_CNT_PORT 0x1f2
+#define PRI_SECT_ADDR1_PORT 0x1f3
+#define PRI_SECT_ADDR2_PORT 0x1f4
+#define PRI_SECT_ADDR3_PORT 0x1f5
+#define PRI_DRV_SEL_PORT 0x1f6
+#define PRI_CMD_PORT 0x1f7
+#define PRI_CTRL_PORT 0x3f6
+#define PRI_ADDR_REG_PORT 0x3f7
+
+#define SEC_DATA_PORT 0x170
+#define SEC_FEATURES_PORT 0x171
+#define SEC_SECT_CNT_PORT 0x172
+#define SEC_SECT_ADDR1_PORT 0x173
+#define SEC_SECT_ADDR2_PORT 0x174
+#define SEC_SECT_ADDR3_PORT 0x175
+#define SEC_DRV_SEL_PORT 0x176
+#define SEC_CMD_PORT 0x177
+#define SEC_CTRL_PORT 0x376
+#define SEC_ADDR_REG_PORT 0x377
+
+
+
+
+
+#define PACKET_SIZE 12
+
+
+
+// FLAT MODE
+// Open a image. Returns non-negative if successful.
+//int open (const char* pathname);
+
+// Open an image with specific flags. Returns non-negative if successful.
+int rd_open (const char* pathname, int flags);
+
+// Close the image.
+void rd_close ();
+
+// Position ourselves. Return the resulting offset from the
+// beginning of the file.
+off_t rd_lseek (off_t offset, int whence);
+
+// Read count bytes to the buffer buf. Return the number of
+// bytes read (count).
+ssize_t rd_read (void* buf, size_t count);
+
+// Write count bytes from buf. Return the number of bytes
+// written (count).
+ssize_t rd_write (const void* buf, size_t count);
+
+
+
-#define RD_PANIC(_f, _a...) \
- do { \
- PrintDebug("ramdisk.c(%d) " _f, __LINE__, ## _a); \
- while(1); \
- } \
- while(0)
-
-#define RD_ERROR(_f, _a...) PrintTrace("\nramdisk.c(%d) " _f, __LINE__, ## _a)
/*
* Debug facilities
#define INT13_ELTORITO 0xe2 //0x2fa
#define INT13_DISKETTE_FUNCTION 0xe3 //0x2fb
-// some packet handling macros
-#define EXTRACT_FIELD(arr,byte,start,num_bits) (((arr)[(byte)] >> (start)) & ((1 << (num_bits)) - 1))
-#define get_packet_field(c,b,s,n) (EXTRACT_FIELD((SELECTED_CONTROLLER((c)).buffer),(b),(s),(n)))
-#define get_packet_byte(c,b) (SELECTED_CONTROLLER((c)).buffer[(b)])
-#define get_packet_word(c,b) (((uint16)SELECTED_CONTROLLER((c)).buffer[(b)] << 8) | SELECTED_CONTROLLER((c)).buffer[(b)+1])
-
-
-#define CONTROLLER(c,a) (channels[(c)].drives[(a)]).controller
-#define DRIVE(c,a) (channels[(c)].drives[(a)])
-#define SELECTED_CONTROLLER(c) (CONTROLLER((c), channels[(c)].drive_select))
-#define SELECTED_DRIVE(c) (DRIVE((c), channels[(c)].drive_select))
-
-
-#define DRIVE_IS_PRESENT(c,a) (channels[(c)].drives[(a)].device_type != IDE_NONE)
-#define DRIVE_IS_HD(c,a) (channels[(c)].drives[(a)].device_type == IDE_DISK)
-#define DRIVE_IS_CD(c,a) (channels[(c)].drives[(a)].device_type == IDE_CDROM)
-#define SELECTED_MODEL(c) (channels[(c)].drives[channels[(c)].drive_select].model_no)
-
-#define MASTER_SELECTED(c) (!channels[(c)].drive_select)
-#define SLAVE_SELECTED(c) (channels[(c)].drive_select)
-
-#define SELECTED_IS_PRESENT(c) (DRIVE_IS_PRESENT((c),SLAVE_SELECTED((c))))
-#define SELECTED_IS_HD(c) (DRIVE_IS_HD((c),SLAVE_SELECTED((c))))
-#define SELECTED_IS_CD(c) (DRIVE_IS_CD((c),SLAVE_SELECTED((c))))
-#define ANY_IS_PRESENT(c) (DRIVE_IS_PRESENT((c),0) || DRIVE_IS_PRESENT((c),1))
-#define SELECTED_TYPE_STRING(channel) ((SELECTED_IS_CD(channel)) ? "CD-ROM" : "NONE")
-
-#define WRITE_FEATURES(c,a) do { uint8 _a = a; CONTROLLER((c),0).features = _a; CONTROLLER((c),1).features = _a; } while(0)
-#define WRITE_SECTOR_COUNT(c,a) do { uint8 _a = a; CONTROLLER((c),0).sector_count = _a; CONTROLLER((c),1).sector_count = _a; } while(0)
-#define WRITE_SECTOR_NUMBER(c,a) do { uint8 _a = a; CONTROLLER((c),0).sector_no = _a; CONTROLLER((c),1).sector_no = _a; } while(0)
-#define WRITE_CYLINDER_LOW(c,a) do { uint8 _a = a; CONTROLLER((c),0).cylinder_no = (CONTROLLER((c),0).cylinder_no & 0xff00) | _a; CONTROLLER((c),1).cylinder_no = (CONTROLLER((c),1).cylinder_no & 0xff00) | _a; } while(0)
-#define WRITE_CYLINDER_HIGH(c,a) do { uint16 _a = a; CONTROLLER((c),0).cylinder_no = (_a << 8) | (CONTROLLER((c),0).cylinder_no & 0xff); CONTROLLER((c),1).cylinder_no = (_a << 8) | (CONTROLLER((c),1).cylinder_no & 0xff); } while(0)
-#define WRITE_HEAD_NO(c,a) do { uint8 _a = a; CONTROLLER((c),0).head_no = _a; CONTROLLER((c),1).head_no = _a; } while(0)
-#define WRITE_LBA_MODE(c,a) do { uint8 _a = a; CONTROLLER((c),0).lba_mode = _a; CONTROLLER((c),1).lba_mode = _a; } while(0)
-
-
-
-#define GOTO_RETURN_VALUE if(io_len==4){\
- goto return_value32;\
- }\
- else if(io_len==2){\
- value16=(Bit16u)value32;\
- goto return_value16;\
- }\
- else{\
- value8=(Bit8u)value32;\
- goto return_value8;\
- }
-
-#define UNUSED(x) ((void)x)
-
-#define PACKET_SIZE 12
-static struct ramdisk_t *ramdisk_state;
+static const char cdrom_str[] = "CD-ROM";
+static const char harddisk_str[] = "HARDDISK";
+static const char none_str[] = "NONE";
+static inline const char * device_type_to_str(device_type_t type) {
+ switch (type) {
+ case IDE_DISK:
+ return harddisk_str;
+ case IDE_CDROM:
+ return cdrom_str;
+ case IDE_NONE:
+ return none_str;
+ default:
+ return NULL;
+ }
+}
+static inline void write_features(struct channel_t * channel, uchar_t value) {
+ channel->drives[0].controller.features = value;
+ channel->drives[1].controller.features = value;
+}
-////////////////////////////////////////////////////////////////////////////
-/*
- * Static routines
- */
+static inline void write_sector_count(struct channel_t * channel, uchar_t value) {
+ channel->drives[0].controller.sector_count = value;
+ channel->drives[1].controller.sector_count = value;
+}
-static
-uint_t ramdisk_read_port(ushort_t port,
- void *src,
- uint_t length,
- struct vm_device *dev);
+static inline void write_sector_number(struct channel_t * channel, uchar_t value) {
+ channel->drives[0].controller.sector_no = value;
+ channel->drives[1].controller.sector_no = value;
+}
-static
-uint_t ramdisk_write_port(ushort_t port,
- void *src,
- uint_t length,
- struct vm_device *dev);
-static
-uint_t ramdisk_read_port_ignore(ushort_t port,
- void *src,
- uint_t length,
- struct vm_device *dev);
+static inline void write_cylinder_low(struct channel_t * channel, uchar_t value) {
+ channel->drives[0].controller.cylinder_no &= 0xff00;
+ channel->drives[0].controller.cylinder_no |= value;
+ channel->drives[1].controller.cylinder_no &= 0xff00;
+ channel->drives[1].controller.cylinder_no |= value;
+}
-static
-uint_t ramdisk_write_port_ignore(ushort_t port,
- void *src,
- uint_t length,
- struct vm_device *dev);
+static inline void write_cylinder_high(struct channel_t * channel, uchar_t value) {
+ ushort_t val2 = value;
+ val2 = val2 << 8;
+ channel->drives[0].controller.cylinder_no &= 0x00ff;
+ channel->drives[0].controller.cylinder_no |= (val2 & 0xff00);
+ channel->drives[1].controller.cylinder_no &= 0x00ff;
+ channel->drives[1].controller.cylinder_no |= (val2 & 0xff00);
+}
-static
-Bit32u rd_read_handler(struct channel_t *channels, Bit32u address, unsigned io_len);
+static inline void write_head_no(struct channel_t * channel, uchar_t value) {
+ channel->drives[0].controller.head_no = value;
+ channel->drives[1].controller.head_no = value;
+}
-static
-void rd_write_handler(struct channel_t *channels, Bit32u address,
- Bit32u value, unsigned io_len);
+static inline void write_lba_mode(struct channel_t * channel, uchar_t value) {
+ channel->drives[0].controller.lba_mode = value;
+ channel->drives[1].controller.lba_mode = value;
+}
+static inline uint_t get_channel_no(struct ramdisk_t * ramdisk, struct channel_t * channel) {
+ return (((uchar_t *)channel - (uchar_t *)(ramdisk->channels)) / sizeof(struct channel_t));
+}
-/*
- * ATAPI routines
- */
+static inline uint_t get_drive_no(struct channel_t * channel, struct drive_t * drive) {
+ return (((uchar_t *)drive - (uchar_t*)(channel->drives)) / sizeof(struct drive_t));
+}
-static
-void rd_identify_ATAPI_drive(struct channel_t *channels, Bit8u channel);
+static inline struct drive_t * get_selected_drive(struct channel_t * channel) {
+ return &(channel->drives[channel->drive_select]);
+}
-static
-void rd_init_send_atapi_command(struct channel_t *channels, Bit8u channel, Bit8u command, int req_length, int alloc_length, bool lazy /*= false*/);
+static inline int is_primary_port(struct ramdisk_t * ramdisk, ushort_t port) {
+ switch(port)
+ {
+ case PRI_DATA_PORT:
+ case PRI_FEATURES_PORT:
+ case PRI_SECT_CNT_PORT:
+ case PRI_SECT_ADDR1_PORT:
+ case PRI_SECT_ADDR2_PORT:
+ case PRI_SECT_ADDR3_PORT:
+ case PRI_DRV_SEL_PORT:
+ case PRI_CMD_PORT:
+ case PRI_CTRL_PORT:
+ return 1;
+ default:
+ return 0;
+ }
+}
-static
-void rd_ready_to_send_atapi(struct channel_t *channels, Bit8u channel);
-static
-void rd_atapi_cmd_error(struct channel_t *channels, Bit8u channel, sense_t sense_key, asc_t asc);
+static inline int is_secondary_port(struct ramdisk_t * ramdisk, ushort_t port) {
+ switch(port)
+ {
+ case SEC_DATA_PORT:
+ case SEC_FEATURES_PORT:
+ case SEC_SECT_CNT_PORT:
+ case SEC_SECT_ADDR1_PORT:
+ case SEC_SECT_ADDR2_PORT:
+ case SEC_SECT_ADDR3_PORT:
+ case SEC_DRV_SEL_PORT:
+ case SEC_CMD_PORT:
+ case SEC_CTRL_PORT:
+ return 1;
+ default:
+ return 0;
+ }
+}
-static
-void rd_init_mode_sense_single(struct channel_t *channels, Bit8u channel, const void* src, int size);
+static inline int num_drives_on_channel(struct channel_t * channel) {
+ if ((channel->drives[0].device_type == IDE_NONE) &&
+ (channel->drives[1].device_type == IDE_NONE)) {
+ return 0;
+ } else if ((channel->drives[0].device_type != IDE_NONE) &&
+ (channel->drives[1].device_type != IDE_NONE)) {
+ return 2;
+ } else {
+ return 1;
+ }
+}
-static
-void rd_atapi_cmd_nop(struct channel_t *channels, Bit8u channel);
-static
-void rd_command_aborted(struct channel_t *channels, Bit8u channel, unsigned value);
+static inline uchar_t extract_bits(uchar_t * buf, uint_t buf_offset, uint_t bit_offset, uint_t num_bits) {
+ uchar_t val = buf[buf_offset];
+ val = val >> bit_offset;
+ val &= ((1 << num_bits) -1);
+ return val;
+}
-/*
- * Interrupt handling
- */
-static
-void rd_raise_interrupt(struct channel_t *channels, Bit8u channel);
+static inline uchar_t get_packet_field(struct channel_t * channel, uint_t packet_offset, uint_t bit_offset, uint_t num_bits) {
+ struct drive_t * drive = get_selected_drive(channel);
+ return extract_bits(drive->controller.buffer, packet_offset, bit_offset, num_bits);
+}
-static
-void rd_lower_irq(struct vm_device *dev, Bit32u irq);
+static inline uchar_t get_packet_byte(struct channel_t * channel, uint_t offset) {
+ struct drive_t * drive = get_selected_drive(channel);
+ return drive->controller.buffer[offset];
+}
+static inline uint16_t get_packet_word(struct channel_t * channel, uint_t offset) {
+ struct drive_t * drive = get_selected_drive(channel);
+ uint16_t val = drive->controller.buffer[offset];
+ val = val << 8;
+ val |= drive->controller.buffer[offset + 1];
+ return val;
+}
-/*
- * Helper routines
- */
-uint16 rd_read_16bit(const uint8* buf)
-{
+static inline uint16_t rd_read_16bit(const uint8_t* buf) {
return (buf[0] << 8) | buf[1];
}
-uint32 rd_read_32bit(const uint8* buf)
-{
+static inline uint32_t rd_read_32bit(const uint8_t* buf) {
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
}
-////////////////////////////////////////////////////////////////////
-
-
-void rd_print_state(struct ramdisk_t *ramdisk,
- struct vm_device *dev)
-//Bit32u rd_init_harddrive(struct channel_t *channels)
-{
-
- uchar_t channel;
- uchar_t device;
- struct channel_t *channels = (struct channel_t *)(&(ramdisk->channels));
+////////////////////////////////////////////////////////////////////////////
- for (channel = 0; channel < MAX_ATA_CHANNEL; channel++)
- memset((char *)(channels + channel), 0, sizeof(struct channel_t));
- Ramdisk_Print("sizeof(*channels) = %d\n", sizeof((*channels)));
- Ramdisk_Print("sizeof(channles->drives[0].controller) = %d\n", sizeof((channels->drives[0].controller)));
- Ramdisk_Print("sizeof(channles->drives[0].cdrom) = %d\n", sizeof((channels->drives[0].cdrom)));
- Ramdisk_Print("sizeof(channles->drives[0].sense) = %d\n", sizeof((channels->drives[0].sense)));
- Ramdisk_Print("sizeof(channles->drives[0].atapi) = %d\n", sizeof((channels->drives[0].atapi)));
+/*
+ * ATAPI routines
+ */
- Ramdisk_Print("sizeof(channles->drives[0].controller.status) = %d\n", sizeof((channels->drives[0].controller.status)));
- Ramdisk_Print("sizeof(channles->drives[0].controller.sector_count) = %d\n", sizeof((channels->drives[0].controller.sector_count)));
- Ramdisk_Print("sizeof(channles->drives[0].controller.interrupt_reason) = %d\n", sizeof((channels->drives[0].controller.interrupt_reason)));
+static void rd_init_mode_sense_single(struct vm_device * dev, struct channel_t * channel, const void * src, int size);
- Ramdisk_Print("sizeof(channles->drives[0].controller.cylinder_no) = %d\n", sizeof((channels->drives[0].controller.cylinder_no)));
- Ramdisk_Print("sizeof(channles->drives[0].controller.byte_count) = %d\n", sizeof((channels->drives[0].controller.byte_count)));
+static void rd_command_aborted(struct vm_device * dev, struct channel_t * channel, unsigned value);
- Ramdisk_Print("sizeof(channles->drives[0].controller.control) = %d\n", sizeof((channels->drives[0].controller.control)));
- for (channel = 0; channel < MAX_ATA_CHANNEL; channel++){
-
- for (device = 0; device < 2; device++){
-
- // Initialize controller state, even if device is not present
- Ramdisk_Print("channels[%d].drives[%d].controller.status.busy = %d\n",channel, device, channels[channel].drives[device].controller.status.busy);
- Ramdisk_Print("channels[%d].drives[%d].controller.status.drive_ready = %d\n", channel, device, channels[channel].drives[device].controller.status.drive_ready);
- Ramdisk_Print("channels[%d].drives[%d].controller.status.write_fault = %d\n", channel, device, channels[channel].drives[device].controller.status.write_fault);
- Ramdisk_Print("channels[%d].drives[%d].controller.status.seek_complete = %d\n", channel, device, channels[channel].drives[device].controller.status.seek_complete);
- Ramdisk_Print("channels[%d].drives[%d].controller.status.drq = %d\n", channel, device, channels[channel].drives[device].controller.status.drq);
- Ramdisk_Print("channels[%d].drives[%d].controller.status.corrected_data = %d\n", channel, device, channels[channel].drives[device].controller.status.corrected_data);
- Ramdisk_Print("channels[%d].drives[%d].controller.status.index_pulse = %d\n", channel, device, channels[channel].drives[device].controller.status.index_pulse);
- Ramdisk_Print("channels[%d].drives[%d].controller.status.index_pulse_count = %d\n", channel, device, channels[channel].drives[device].controller.status.index_pulse_count);
- Ramdisk_Print("channels[%d].drives[%d].controller.status.err = %d\n", channel, device, channels[channel].drives[device].controller.status.err);
+static int handle_atapi_packet_command(struct vm_device * dev,
+ struct channel_t * channel,
+ ushort_t val);
+static int rd_init_send_atapi_command(struct vm_device * dev,
+ struct channel_t * channel,
+ Bit8u command, int req_length,
+ int alloc_length, bool lazy);
- Ramdisk_Print("channels[%d].drives[%d].controller.error_register = %d\n", channel, device, channels[channel].drives[device].controller.error_register);
- Ramdisk_Print("channels[%d].drives[%d].controller.head_no = %d\n", channel, device, channels[channel].drives[device].controller.head_no);
- Ramdisk_Print("channels[%d].drives[%d].controller.sector_count = %d\n", channel, device, channels[channel].drives[device].controller.sector_count);
- Ramdisk_Print("channels[%d].drives[%d].controller.sector_no = %d\n", channel, device, channels[channel].drives[device].controller.sector_no);
- Ramdisk_Print("channels[%d].drives[%d].controller.cylinder_no = %d\n", channel, device, channels[channel].drives[device].controller.cylinder_no);
- Ramdisk_Print("channels[%d].drives[%d].controller.current_command = %02x\n", channel, device, channels[channel].drives[device].controller.current_command);
- Ramdisk_Print("channels[%d].drives[%d].controller.buffer_index = %d\n", channel, device, channels[channel].drives[device].controller.buffer_index);
+static void rd_ready_to_send_atapi(struct vm_device * dev,
+ struct channel_t * channel);
+static void rd_atapi_cmd_error(struct vm_device * dev,
+ struct channel_t * channel,
+ sense_t sense_key, asc_t asc);
- Ramdisk_Print("channels[%d].drives[%d].controller.control.reset = %d\n", channel, device, channels[channel].drives[device].controller.control.reset);
- Ramdisk_Print("channels[%d].drives[%d].controller.control.disable_irq = %d\n", channel, device, channels[channel].drives[device].controller.control.disable_irq);
+static void rd_atapi_cmd_nop(struct vm_device * dev, struct channel_t * channel);
+static void rd_identify_ATAPI_drive(struct vm_device * dev, struct channel_t * channel);
- Ramdisk_Print("channels[%d].drives[%d].controller.reset_in_progress = %d\n", channel, device, channels[channel].drives[device].controller.reset_in_progress);
- Ramdisk_Print("channels[%d].drives[%d].controller.sectors_per_block = %02x\n", channel, device, channels[channel].drives[device].controller.sectors_per_block);
- Ramdisk_Print("channels[%d].drives[%d].controller.lba_mode = %d\n", channel, device, channels[channel].drives[device].controller.lba_mode);
- Ramdisk_Print("channels[%d].drives[%d].controller.features = %d\n", channel, device, channels[channel].drives[device].controller.features);
+/*
+ * Interrupt handling
+ */
+static void rd_raise_interrupt(struct vm_device * dev, struct channel_t * channel);
+static void rd_lower_irq(struct vm_device *dev, Bit32u irq);
- Ramdisk_Print("channels[%d].drives[%d].model_no = %s\n", channel, device, channels[channel].drives[device].model_no);
- Ramdisk_Print("channels[%d].drives[%d].device_type = %d\n", channel, device, channels[channel].drives[device].device_type);
- Ramdisk_Print("channels[%d].drives[%d].cdrom.locked = %d\n", channel, device, channels[channel].drives[device].cdrom.locked);
- Ramdisk_Print("channels[%d].drives[%d].sense.sense_key = %d\n", channel, device, channels[channel].drives[device].sense.sense_key);
- Ramdisk_Print("channels[%d].drives[%d].sense.asc = %d\n", channel, device, channels[channel].drives[device].sense.asc);
- Ramdisk_Print("channels[%d].drives[%d].sense.ascq = %d\n", channel, device, channels[channel].drives[device].sense.ascq);
+/*
+ * Helper routines
+ */
- Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.c_d = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.c_d);
- Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.i_o = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.i_o);
- Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.rel = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.rel);
+#ifdef DEBUG_RAMDISK
+static void rd_print_state(struct ramdisk_t *ramdisk);
+static int check_bit_fields(struct controller_t * controller);
+#endif
+////////////////////////////////////////////////////////////////////
- Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.tag = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.tag);
- Ramdisk_Print("channels[%d].drives[%d].cdrom.ready = %d\n", channel, device, channels[channel].drives[device].cdrom.ready);
-
- }//for device
- }//for channel
-
- return;
-}
-Bit32u rd_init_harddrive(struct ramdisk_t *ramdisk,
- struct vm_device *dev)
-{
-
- uchar_t channel;
- uchar_t device;
+static Bit32u rd_init_hardware(struct ramdisk_t *ramdisk) {
+ uint_t channel_num;
+ uint_t device;
struct channel_t *channels = (struct channel_t *)(&(ramdisk->channels));
- Ramdisk_Print("[rd_init_harddrive]\n");
- for (channel = 0; channel < MAX_ATA_CHANNEL; channel++)
- memset((char *)(channels + channel), 0, sizeof(struct channel_t));
+ PrintDebug("[rd_init_harddrive]\n");
+ for (channel_num = 0; channel_num < MAX_ATA_CHANNEL; channel_num++) {
+ memset((char *)(channels + channel_num), 0, sizeof(struct channel_t));
+ }
- for (channel = 0; channel < MAX_ATA_CHANNEL; channel++){
-
- channels[channel].ioaddr1 = 0x0;
- channels[channel].ioaddr2 = 0x0;
- channels[channel].irq = 0;
+ for (channel_num = 0; channel_num < MAX_ATA_CHANNEL; channel_num++){
+ struct channel_t * channel = &(channels[channel_num]);
+
+ channel->ioaddr1 = 0x0;
+ channel->ioaddr2 = 0x0;
+ channel->irq = 0;
for (device = 0; device < 2; device++){
+ struct drive_t * drive = &(channel->drives[device]);
+ struct controller_t * controller = &(drive->controller);
+
+ controller->status.busy = 0;
+ controller->status.drive_ready = 1;
+ controller->status.write_fault = 0;
+ controller->status.seek_complete = 1;
+ controller->status.drq = 0;
+ controller->status.corrected_data = 0;
+ controller->status.index_pulse = 0;
+ controller->status.index_pulse_count = 0;
+ controller->status.err = 0;
+
+ controller->error_register = 0x01; // diagnostic code: no error
+ controller->head_no = 0;
+ controller->sector_count = 1;
+ controller->sector_no = 1;
+ controller->cylinder_no = 0;
+ controller->current_command = 0x00;
+ controller->buffer_index = 0;
+
+ controller->control.reset = 0;
+ controller->control.disable_irq = 0;
+ controller->reset_in_progress = 0;
+
+ controller->sectors_per_block = 0x80;
+ controller->lba_mode = 0;
-
- CONTROLLER(channel,device).status.busy = 0;
- CONTROLLER(channel,device).status.drive_ready = 1;
- CONTROLLER(channel,device).status.write_fault = 0;
- CONTROLLER(channel,device).status.seek_complete = 1;
- CONTROLLER(channel,device).status.drq = 0;
- CONTROLLER(channel,device).status.corrected_data = 0;
- CONTROLLER(channel,device).status.index_pulse = 0;
- CONTROLLER(channel,device).status.index_pulse_count = 0;
- CONTROLLER(channel,device).status.err = 0;
-
- CONTROLLER(channel,device).error_register = 0x01; // diagnostic code: no error
- CONTROLLER(channel,device).head_no = 0;
- CONTROLLER(channel,device).sector_count = 1;
- CONTROLLER(channel,device).sector_no = 1;
- CONTROLLER(channel,device).cylinder_no = 0;
- CONTROLLER(channel,device).current_command = 0x00;
- CONTROLLER(channel,device).buffer_index = 0;
-
- CONTROLLER(channel,device).control.reset = 0;
- CONTROLLER(channel,device).control.disable_irq = 0;
- CONTROLLER(channel,device).reset_in_progress = 0;
-
- CONTROLLER(channel,device).sectors_per_block = 0x80;
- CONTROLLER(channel,device).lba_mode = 0;
- CONTROLLER(channel,device).features = 0;
+ controller->features = 0;
- // If not present
- channels[channel].drives[device].device_type = IDE_NONE;
+ // If not present
+ drive->device_type = IDE_NONE;
// Make model string
- strncpy((char*)channels[channel].drives[device].model_no,
- "", 40);
- while(strlen((char *)channels[channel].drives[device].model_no) < 40) {
- strcat ((char*)channels[channel].drives[device].model_no, " ");
+ strncpy((char*)(drive->model_no), "", 40);
+ while(strlen((char *)(drive->model_no)) < 40) {
+ strcat ((char*)(drive->model_no), " ");
}
-// Ramdisk_Print("channels[%d].drives[%d].controller.current_command = %02x\n", channel, device, channels[channel].drives[device].controller.current_command);
-// Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.c_d = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.c_d);
-
-// Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.i_o = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.i_o);
-// Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.rel = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.rel);
-
-// Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.tag = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.tag);
-
-// Ramdisk_Print("channels[%d].drives[%d].controller.control.disable_irq = %d\n", channel, device, channels[channel].drives[device].controller.control.disable_irq);
-
- if (channel == 1) {
+ if (channel_num == 1) {
- channels[channel].ioaddr1 = 0x170;
- channels[channel].ioaddr2 = 0x370;
- channels[channel].irq = 15;
- channels[channel].drive_select = 0;
+ channel->ioaddr1 = 0x170;
+ channel->ioaddr2 = 0x370;
+ channel->irq = 15;
+ channel->drive_select = 0;
if (device == 0) {
// Make model string
- strncpy((char*)channels[channel].drives[device].model_no,
- "Zheng's Ramdisk", 40);
- while (strlen((char *)channels[channel].drives[device].model_no) < 40) {
- strcat ((char*)channels[channel].drives[device].model_no, " ");
+ strncpy((char*)(drive->model_no), "V3VEE Ramdisk", 40);
+ while (strlen((char *)(drive->model_no)) < 40) {
+ strcat ((char*)(drive->model_no), " ");
}
-
- Ramdisk_Print("CDROM on target %d/%d\n", channel, device);
- channels[channel].drives[device].device_type = IDE_CDROM;
- channels[channel].drives[device].cdrom.locked = 0;
- channels[channel].drives[device].sense.sense_key = SENSE_NONE;
- channels[channel].drives[device].sense.asc = 0;
- channels[channel].drives[device].sense.ascq = 0;
+ PrintDebug("CDROM on target %d/%d\n", channel_num, device);
-
- //Check bit fields
- channels[channel].drives[device].controller.sector_count = 0;
- channels[channel].drives[device].controller.interrupt_reason.c_d = 1;
- if (channels[channel].drives[device].controller.sector_count != 0x01) {
- Ramdisk_Print("interrupt reason bit field error\n");
- return INTR_REASON_BIT_ERR;
- }
-
- channels[channel].drives[device].controller.sector_count = 0;
- channels[channel].drives[device].controller.interrupt_reason.i_o = 1;
- if (channels[channel].drives[device].controller.sector_count != 0x02) {
- Ramdisk_Print("interrupt reason bit field error\n");
- return INTR_REASON_BIT_ERR;
- }
+ drive->device_type = IDE_CDROM;
+ drive->cdrom.locked = 0;
+ drive->sense.sense_key = SENSE_NONE;
+ drive->sense.asc = 0;
+ drive->sense.ascq = 0;
- channels[channel].drives[device].controller.sector_count = 0;
- channels[channel].drives[device].controller.interrupt_reason.rel = 1;
- if (channels[channel].drives[device].controller.sector_count != 0x04) {
- Ramdisk_Print("interrupt reason bit field error\n");
- return INTR_REASON_BIT_ERR;
- }
-
- channels[channel].drives[device].controller.sector_count = 0;
- channels[channel].drives[device].controller.interrupt_reason.tag = 3;
- if (channels[channel].drives[device].controller.sector_count != 0x18) {
- Ramdisk_Print("interrupt reason bit field error\n");
+#ifdef DEBUG_RAMDISK
+ if (check_bit_fields(controller) == INTR_REASON_BIT_ERR) {
+ PrintDebug("interrupt reason: bit field error\n");
return INTR_REASON_BIT_ERR;
}
+#endif
-
- channels[channel].drives[device].controller.sector_count = 0;
+ controller->sector_count = 0;
// allocate low level driver
- channels[channel].drives[device].cdrom.cd = (struct cdrom_interface*)V3_Malloc(sizeof(struct cdrom_interface));
- Ramdisk_Print("cd = %x\n", channels[channel].drives[device].cdrom.cd);
- V3_ASSERT(channels[channel].drives[device].cdrom.cd != NULL);
+ drive->cdrom.cd = (struct cdrom_interface *)V3_Malloc(sizeof(struct cdrom_interface));
+ PrintDebug("cd = %x\n", drive->cdrom.cd);
+ V3_ASSERT(drive->cdrom.cd != NULL);
- struct cdrom_interface *cdif = channels[channel].drives[device].cdrom.cd;
+ struct cdrom_interface * cdif = drive->cdrom.cd;
memset(cdif, 0, sizeof(struct cdrom_interface));
init_cdrom(cdif);
cdif->ops.init(cdif);
- Ramdisk_Print("\t\tCD on ata%d-%d: '%s'\n",channel, device, "");
+ PrintDebug("\t\tCD on ata%d-%d: '%s'\n",
+ channel_num,
+ device, "");
- if((channels[channel].drives[device].cdrom.cd->ops).insert_cdrom(cdif, NULL)) {
- Ramdisk_Print("\t\tMedia present in CD-ROM drive\n");
- channels[channel].drives[device].cdrom.ready = 1;
- channels[channel].drives[device].cdrom.capacity = channels[channel].drives[device].cdrom.cd->ops.capacity(cdif);
+ if((drive->cdrom.cd->ops).insert_cdrom(cdif, NULL)) {
+ PrintDebug("\t\tMedia present in CD-ROM drive\n");
+ drive->cdrom.ready = 1;
+ drive->cdrom.capacity = drive->cdrom.cd->ops.capacity(cdif);
} else {
- Ramdisk_Print("\t\tCould not locate CD-ROM, continuing with media not present\n");
- channels[channel].drives[device].cdrom.ready = 0;
+ PrintDebug("\t\tCould not locate CD-ROM, continuing with media not present\n");
+ drive->cdrom.ready = 0;
}
}//if device = 0
}//for device
}//for channel
- ramdisk->private_data = dev;
- ramdisk_state = ramdisk;
- Ramdisk_Print("ramdisk_state = %x\n", ramdisk_state);
- Ramdisk_Print("ramdisk = %x\n", ramdisk);
- // rd_print_state(ramdisk, dev);
+#ifdef DEBUG_RAMDISK
+ rd_print_state(ramdisk);
+#endif
return 0;
}
-void rd_reset_harddrive(struct ramdisk_t *ramdisk, unsigned type)
-{
+/*
+ static void rd_reset_harddrive(struct ramdisk_t *ramdisk, unsigned type) {
return;
-}
-
+ }
-void rd_close_harddrive(struct ramdisk_t *ramdisk)
-{
+*/
+static void rd_close_harddrive(struct ramdisk_t *ramdisk) {
return;
}
////////////////////////////////////////////////////////////////////
-static
-Bit32u rd_read_handler(struct channel_t *channels, Bit32u address, unsigned io_len)
-{
- Bit8u value8;
- Bit16u value16;
- Bit32u value32;
- unsigned drive_select;
- unsigned index;
- unsigned increment = 0;
+static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+ struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data);
+ struct channel_t * channel = NULL;
+ struct drive_t * drive = NULL;
+ struct controller_t * controller = NULL;
- Bit8u channel = MAX_ATA_CHANNEL;
- Bit32u port = 0xff; // undefined
-
- Ramdisk_Print("[rd_read_handler]\n");
-
- for (channel=0; channel<MAX_ATA_CHANNEL; channel++) {
- if ((address & 0xfff8) == channels[channel].ioaddr1) {
- port = address - channels[channel].ioaddr1;
- break;
- }
- else if ((address & 0xfff8) == channels[channel].ioaddr2) {
- port = address - channels[channel].ioaddr2 + 0x10;
- break;
- }
- }
- if (channel == MAX_ATA_CHANNEL) {
- if ((address < 0x03f6) || (address > 0x03f7)) {
- RD_PANIC("Error: read: unable to find ATA channel, ioport=0x%04x\n", address);
- return 0;
- } else {
- channel = 0;
- port = address - 0x03e0;
- }
- }
- drive_select = channels[channel].drive_select;
- if (port != 0x00){
- Ramdisk_Print("[R_handler] IO read addr at %x, on drive %d/%d, curcmd = %02x\n", address, channel, drive_select, SELECTED_CONTROLLER(channel).current_command);
- }else{
-
+ if (is_primary_port(ramdisk, port)) {
+ channel = &(ramdisk->channels[0]);
+ } else if (is_secondary_port(ramdisk, port)) {
+ channel = &(ramdisk->channels[1]);
+ } else {
+ PrintError("Invalid Port: %d\n", port);
+ return -1;
}
+
+ drive = get_selected_drive(channel);
+ controller = &(drive->controller);
- struct cdrom_interface *cdif = channels[channel].drives[drive_select].cdrom.cd;
- switch (port) {
+ PrintDebug("[read_data_handler] IO Read at 0x%x, on drive %d/%d (current_cmd = 0x%02x)\n",
+ port,
+ get_channel_no(ramdisk, channel),
+ get_drive_no(channel, drive),
+ controller->current_command);
- case 0x00: // hard disk data (16bit) 0x1f0
+ switch (controller->current_command) {
+ case 0xec: // IDENTIFY DEVICE
+ case 0xa1:
+ {
- switch (SELECTED_CONTROLLER(channel).current_command) {
- case 0xec: // IDENTIFY DEVICE
- case 0xa1:
- index = 0;
- SELECTED_CONTROLLER(channel).status.busy = 0;
- SELECTED_CONTROLLER(channel).status.drive_ready = 1;
- SELECTED_CONTROLLER(channel).status.write_fault = 0;
- SELECTED_CONTROLLER(channel).status.seek_complete = 1;
- SELECTED_CONTROLLER(channel).status.corrected_data = 0;
- SELECTED_CONTROLLER(channel).status.err = 0;
+ controller->status.busy = 0;
+ controller->status.drive_ready = 1;
+ controller->status.write_fault = 0;
+ controller->status.seek_complete = 1;
+ controller->status.corrected_data = 0;
+ controller->status.err = 0;
+
+ /*
+ value32 = controller->buffer[index];
+ index++;
- index = SELECTED_CONTROLLER(channel).buffer_index;
- value32 = SELECTED_CONTROLLER(channel).buffer[index];
- index++;
-
- if (io_len >= 2) {
- value32 |= (SELECTED_CONTROLLER(channel).buffer[index] << 8);
+ if (io_len >= 2) {
+ value32 |= (controller->buffer[index] << 8);
index++;
- }
- if (io_len == 4) {
- value32 |= (SELECTED_CONTROLLER(channel).buffer[index] << 16);
- value32 |= (SELECTED_CONTROLLER(channel).buffer[index+1] << 24);
+ }
+
+ if (io_len == 4) {
+ value32 |= (controller->buffer[index] << 16);
+ value32 |= (controller->buffer[index+1] << 24);
index += 2;
- }
- SELECTED_CONTROLLER(channel).buffer_index = index;
-
- if (SELECTED_CONTROLLER(channel).buffer_index >= 512) {
+ }
- SELECTED_CONTROLLER(channel).status.drq = 0;
+ controller->buffer_index = index;
+ */
+ /* JRL */
+ memcpy(dst, controller->buffer + controller->buffer_index, length);
+ controller->buffer_index += length;
+
+ if (controller->buffer_index >= 512) {
+ controller->status.drq = 0;
}
- GOTO_RETURN_VALUE;
-
- case 0xa0: //send packet cmd
+
+ return length;
+ }
+ case 0xa0: //send packet cmd
+ {
+ uint_t index = controller->buffer_index;
- index = SELECTED_CONTROLLER(channel).buffer_index;
- increment = 0;
- Ramdisk_Print("\t\tatapi.command(%02x), index(%d), cdrom.remaining_blocks(%d)\n", SELECTED_DRIVE(channel).atapi.command, index, SELECTED_DRIVE(channel).cdrom.remaining_blocks);
- // Load block if necessary
- if (index >= 2048) {
- if (index > 2048)
- RD_PANIC("\t\tindex > 2048 : 0x%x\n",index);
- switch (SELECTED_DRIVE(channel).atapi.command) {
- case 0x28: // read (10)
- case 0xa8: // read (12)
-
- if (!SELECTED_DRIVE(channel).cdrom.ready) {
- RD_PANIC("\t\tRead with CDROM not ready\n");
+
+ PrintDebug("\t\tatapi.command(%02x), index(%d), cdrom.remaining_blocks(%d)\n",
+ drive->atapi.command,
+ index,
+ drive->cdrom.remaining_blocks);
+
+ // Load block if necessary
+ if (index >= 2048) {
+
+ if (index > 2048) {
+ PrintError("\t\tindex > 2048 : 0x%x\n", index);
+ return -1;
+ }
+
+ switch (drive->atapi.command) {
+ case 0x28: // read (10)
+ case 0xa8: // read (12)
+ {
+ struct cdrom_interface * cdif = drive->cdrom.cd;
+
+ if (!(drive->cdrom.ready)) {
+ PrintError("\t\tRead with CDROM not ready\n");
+ return -1;
}
- SELECTED_DRIVE(channel).cdrom.cd->ops.read_block(cdif, SELECTED_CONTROLLER(channel).buffer,
- SELECTED_DRIVE(channel).cdrom.next_lba);
- SELECTED_DRIVE(channel).cdrom.next_lba++;
- SELECTED_DRIVE(channel).cdrom.remaining_blocks--;
+ drive->cdrom.cd->ops.read_block(cdif, controller->buffer,
+ drive->cdrom.next_lba);
+ drive->cdrom.next_lba++;
+ drive->cdrom.remaining_blocks--;
- if (!SELECTED_DRIVE(channel).cdrom.remaining_blocks)
- Ramdisk_Print("\t\tLast READ block loaded {CDROM}\n");
- else
- Ramdisk_Print("\t\tREAD block loaded (%d remaining) {CDROM}\n",
- SELECTED_DRIVE(channel).cdrom.remaining_blocks);
+
+ if (!(drive->cdrom.remaining_blocks)) {
+ PrintDebug("\t\tLast READ block loaded {CDROM}\n");
+ } else {
+ PrintDebug("\t\tREAD block loaded (%d remaining) {CDROM}\n",
+ drive->cdrom.remaining_blocks);
+ }
// one block transfered, start at beginning
index = 0;
break;
-
- default: // no need to load a new block
- break;
}
+ default: // no need to load a new block
+ break;
}
+ }
+
- value32 = SELECTED_CONTROLLER(channel).buffer[index+increment];
+ /*
+ increment = 0;
+ value32 = controller->buffer[index + increment];
increment++;
+
if (io_len >= 2) {
- value32 |= (SELECTED_CONTROLLER(channel).buffer[index+increment] << 8);
- increment++;
+ value32 |= (controller->buffer[index + increment] << 8);
+ increment++;
}
+
if (io_len == 4) {
- value32 |= (SELECTED_CONTROLLER(channel).buffer[index+increment] << 16);
- value32 |= (SELECTED_CONTROLLER(channel).buffer[index+increment+1] << 24);
- increment += 2;
+ value32 |= (controller->buffer[index + increment] << 16);
+ value32 |= (controller->buffer[index + increment + 1] << 24);
+ increment += 2;
}
- SELECTED_CONTROLLER(channel).buffer_index = index + increment;
- SELECTED_CONTROLLER(channel).drq_index += increment;
+
+ controller->buffer_index = index + increment;
+ controller->drq_index += increment;
+
+ */
+ /* JRL: CHECK THAT there is enough data in the buffer to copy.... */
+ {
+ memcpy(dst, controller->buffer + index, length);
+
+ controller->buffer_index = index + length;
+ controller->drq_index += length;
+ }
+
+ /* *** */
+
+ if (controller->drq_index >= (unsigned)drive->atapi.drq_bytes) {
+ controller->status.drq = 0;
+ controller->drq_index = 0;
- if (SELECTED_CONTROLLER(channel).drq_index >= (unsigned)SELECTED_DRIVE(channel).atapi.drq_bytes) {
- SELECTED_CONTROLLER(channel).status.drq = 0;
- SELECTED_CONTROLLER(channel).drq_index = 0;
+ drive->atapi.total_bytes_remaining -= drive->atapi.drq_bytes;
+
+ if (drive->atapi.total_bytes_remaining > 0) {
+ // one or more blocks remaining (works only for single block commands)
- SELECTED_DRIVE(channel).atapi.total_bytes_remaining -= SELECTED_DRIVE(channel).atapi.drq_bytes;
+ PrintDebug("\t\tPACKET drq bytes read\n");
+ controller->interrupt_reason.i_o = 1;
+ controller->status.busy = 0;
+ controller->status.drq = 1;
+ controller->interrupt_reason.c_d = 0;
- if (SELECTED_DRIVE(channel).atapi.total_bytes_remaining > 0) {
- // one or more blocks remaining (works only for single block commands)
-
- Ramdisk_Print("\t\tPACKET drq bytes read\n");
- SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
- SELECTED_CONTROLLER(channel).status.busy = 0;
- SELECTED_CONTROLLER(channel).status.drq = 1;
- SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 0;
-
- // set new byte count if last block
- if (SELECTED_DRIVE(channel).atapi.total_bytes_remaining < SELECTED_CONTROLLER(channel).byte_count) {
- SELECTED_CONTROLLER(channel).byte_count = SELECTED_DRIVE(channel).atapi.total_bytes_remaining;
- }
- SELECTED_DRIVE(channel).atapi.drq_bytes = SELECTED_CONTROLLER(channel).byte_count;
-
- rd_raise_interrupt(channels, channel);
- } else {
- // all bytes read
- Ramdisk_Print("\t\tPACKET all bytes read\n");
- SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
- SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
- SELECTED_CONTROLLER(channel).status.drive_ready = 1;
- SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
- SELECTED_CONTROLLER(channel).status.busy = 0;
- SELECTED_CONTROLLER(channel).status.drq = 0;
- SELECTED_CONTROLLER(channel).status.err = 0;
-
- rd_raise_interrupt(channels, channel);
+ // set new byte count if last block
+ if (drive->atapi.total_bytes_remaining < controller->byte_count) {
+ controller->byte_count = drive->atapi.total_bytes_remaining;
}
+ drive->atapi.drq_bytes = controller->byte_count;
+
+ rd_raise_interrupt(dev, channel);
+ } else {
+ // all bytes read
+ PrintDebug("\t\tPACKET all bytes read\n");
+
+ controller->interrupt_reason.i_o = 1;
+ controller->interrupt_reason.c_d = 1;
+ controller->status.drive_ready = 1;
+ controller->interrupt_reason.rel = 0;
+ controller->status.busy = 0;
+ controller->status.drq = 0;
+ controller->status.err = 0;
+
+ rd_raise_interrupt(dev, channel);
}
- GOTO_RETURN_VALUE;
- break;
-
- default:
- Ramdisk_Print("\t\tread need support more command: %02x\n", SELECTED_CONTROLLER(channel).current_command);
+ }
+ return length;
break;
}
- ///////////////////////////////////////////
- case 0x01: // hard disk error register 0x1f1
-
- SELECTED_CONTROLLER(channel).status.err = 0;
- value8 = (!SELECTED_IS_PRESENT(channel)) ? 0 : SELECTED_CONTROLLER(channel).error_register;
- goto return_value8;
- break;
- case 0x02: // hard disk sector count / interrupt reason 0x1f2
- value8 = (!SELECTED_IS_PRESENT(channel)) ? 0 : SELECTED_CONTROLLER(channel).sector_count;
- goto return_value8;
+ default:
+ PrintDebug("\t\tread need support more command: %02x\n", controller->current_command);
break;
- case 0x03: // sector number 0x1f3
- value8 = (!SELECTED_IS_PRESENT(channel)) ? 0 : SELECTED_CONTROLLER(channel).sector_no;
- goto return_value8;
- case 0x04: // cylinder low 0x1f4
- // -- WARNING : On real hardware the controller registers are shared between drives.
- // So we must respond even if the select device is not present. Some OS uses this fact
- // to detect the disks.... minix2 for example
- value8 = (!ANY_IS_PRESENT(channel)) ? 0 : (SELECTED_CONTROLLER(channel).cylinder_no & 0x00ff);
- goto return_value8;
- case 0x05: // cylinder high 0x1f5
- // -- WARNING : On real hardware the controller registers are shared between drives.
- // So we must respond even if the select device is not present. Some OS uses this fact
- // to detect the disks.... minix2 for example
- value8 = (!ANY_IS_PRESENT(channel)) ? 0 : SELECTED_CONTROLLER(channel).cylinder_no >> 8;
- goto return_value8;
+ }
+
+ return -1;
+}
+
+
+
+
+static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+ struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data);
+ struct channel_t * channel = NULL;
+ struct drive_t * drive = NULL;
+ struct controller_t * controller = NULL;
+
+ if (is_primary_port(ramdisk, port)) {
+ channel = &(ramdisk->channels[0]);
+ } else if (is_secondary_port(ramdisk, port)) {
+ channel = &(ramdisk->channels[1]);
+ } else {
+ PrintError("Invalid Port: %d\n", port);
+ return -1;
+ }
+
+ drive = get_selected_drive(channel);
+ controller = &(drive->controller);
+
+ PrintDebug("[write_data_handler] IO write at 0x%x, current_cmd = 0x%02x\n",
+ port, controller->current_command);
+
+ switch (controller->current_command) {
+ case 0x30: // WRITE SECTORS
+ PrintError("\t\tneed to implement 0x30(write sector) to port 0x%x\n", port);
+ return -1;
- case 0x06: // hard disk drive and head register 0x1f6
- // b7 Extended data field for ECC
- // b6/b5: Used to be sector size. 00=256,01=512,10=1024,11=128
- // Since 512 was always used, bit 6 was taken to mean LBA mode:
- // b6 1=LBA mode, 0=CHS mode
- // b5 1
- // b4: DRV
- // b3..0 HD3..HD0
- value8 = (1 << 7) |
- ((SELECTED_CONTROLLER(channel).lba_mode>0) << 6) |
- (1 << 5) | // 01b = 512 sector size
- (channels[channel].drive_select << 4) |
- (SELECTED_CONTROLLER(channel).head_no << 0);
- goto return_value8;
- break;
- //CONTROLLER(channel,0).lba_mode
+ case 0xa0: // PACKET
- case 0x07: // Hard Disk Status 0x1f7
- case 0x16: // Hard Disk Alternate Status 0x3f6
- if (!ANY_IS_PRESENT(channel)) {
- // (mch) Just return zero for these registers
- value8 = 0;
- } else {
- value8 = (
- (SELECTED_CONTROLLER(channel).status.busy << 7) |
- (SELECTED_CONTROLLER(channel).status.drive_ready << 6) |
- (SELECTED_CONTROLLER(channel).status.write_fault << 5) |
- (SELECTED_CONTROLLER(channel).status.seek_complete << 4) |
- (SELECTED_CONTROLLER(channel).status.drq << 3) |
- (SELECTED_CONTROLLER(channel).status.corrected_data << 2) |
- (SELECTED_CONTROLLER(channel).status.index_pulse << 1) |
- (SELECTED_CONTROLLER(channel).status.err) );
- SELECTED_CONTROLLER(channel).status.index_pulse_count++;
- SELECTED_CONTROLLER(channel).status.index_pulse = 0;
- if (SELECTED_CONTROLLER(channel).status.index_pulse_count >= INDEX_PULSE_CYCLE) {
- SELECTED_CONTROLLER(channel).status.index_pulse = 1;
- SELECTED_CONTROLLER(channel).status.index_pulse_count = 0;
- }
- }
- if (port == 0x07) {
- rd_lower_irq((struct vm_device *)(ramdisk_state->private_data), channels[channel].irq);
+ if (handle_atapi_packet_command(dev, channel, *(ushort_t *)src) == -1) {
+ return -1;
}
- goto return_value8;
- break;
-
- case 0x17: // Hard Disk Address Register 0x3f7
- // Obsolete and unsupported register. Not driven by hard
- // disk controller. Report all 1's. If floppy controller
- // is handling this address, it will call this function
- // set/clear D7 (the only bit it handles), then return
- // the combined value
- value8 = 0xff;
- goto return_value8;
- break;
+
+ return length;
default:
- RD_PANIC("hard drive: io read to address %x unsupported\n",
- (unsigned) address);
-
-
- ////////////////////////////////////////////
+ PrintError("\t\tIO write(0x%x): current command is %02xh\n",
+ port, controller->current_command);
+
+ return -1;
+ }
+}
+
+
+
+
+
+
+
+static int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+ struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data);
+ struct channel_t * channel = NULL;
+ struct drive_t * drive = NULL;
+ struct controller_t * controller = NULL;
+
+
+ if (length != 1) {
+ PrintError("Invalid Status port read length: %d (port=%d)\n", length, port);
+ return -1;
+ }
+
+ if (is_primary_port(ramdisk, port)) {
+ channel = &(ramdisk->channels[0]);
+ } else if (is_secondary_port(ramdisk, port)) {
+ channel = &(ramdisk->channels[1]);
+ } else {
+ PrintError("Invalid Port: %d\n", port);
+ return -1;
}
- Ramdisk_Print("\t\tError: hard drive: shouldnt get here!\n");
- return 0;
+ drive = get_selected_drive(channel);
+ controller = &(drive->controller);
+
+ PrintDebug("[read_status_handler] IO read at 0x%x, on drive %d/%d\n",
+ port, get_channel_no(ramdisk, channel),
+ channel->drive_select);
+
+
+ if (num_drives_on_channel(channel) == 0) {
+ // (mch) Just return zero for these registers
+ memset(dst, 0, length);
+
+ } else {
+ uchar_t val = (
+ (controller->status.busy << 7) |
+ (controller->status.drive_ready << 6) |
+ (controller->status.write_fault << 5) |
+ (controller->status.seek_complete << 4) |
+ (controller->status.drq << 3) |
+ (controller->status.corrected_data << 2) |
+ (controller->status.index_pulse << 1) |
+ (controller->status.err) );
+
+ memcpy(dst, &val, length);
+
+ controller->status.index_pulse_count++;
+ controller->status.index_pulse = 0;
+
+ if (controller->status.index_pulse_count >= INDEX_PULSE_CYCLE) {
+ controller->status.index_pulse = 1;
+ controller->status.index_pulse_count = 0;
+ }
+ }
-return_value32:
- Ramdisk_Print("\t\t32-bit read from %04x = %08x {%s}\n",
- (unsigned) address, value32, SELECTED_TYPE_STRING(channel));
- return value32;
+ if ((port == SEC_CMD_PORT) || (port == PRI_CMD_PORT)) {
+ rd_lower_irq(dev, channel->irq);
+ }
- return_value16:
- Ramdisk_Print("\t\t16-bit read from %04x = %04x {%s}\n",
- (unsigned) address, value16, SELECTED_TYPE_STRING(channel));
- return value16;
+ return length;
- return_value8:
- Ramdisk_Print("\t\t8-bit read from %x = %02x {%s}\n",
- (unsigned) address, value8, SELECTED_TYPE_STRING(channel));
- return value8;
}
-static
-void rd_write_handler(struct channel_t *channels, Bit32u address,
- Bit32u value, unsigned io_len)
-{
+static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+ struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data);
+ struct channel_t * channel = NULL;
+ struct drive_t * drive = NULL;
+ struct controller_t * controller = NULL;
+ uchar_t value = *(uchar_t *)src;
+
+ if (length != 1) {
+ PrintError("Invalid Command port write length: %d (port=%d)\n", length, port);
+ return -1;
+ }
+
+ if (is_primary_port(ramdisk, port)) {
+ channel = &(ramdisk->channels[0]);
+ } else if (is_secondary_port(ramdisk, port)) {
+ channel = &(ramdisk->channels[1]);
+ } else {
+ PrintError("Invalid Port: %d\n", port);
+ return -1;
+ }
+
+ drive = get_selected_drive(channel);
+ controller = &(drive->controller);
+
+
+ PrintDebug("[write_command_handler] IO write at 0x%x, on drive %d/%d (val = 0x%x)\n",
+ port, get_channel_no(ramdisk, channel),
+ channel->drive_select,
+ value);
+
+ switch (value) {
+ // ATAPI commands
+ case 0xa1: // IDENTIFY PACKET DEVICE
+ {
+ if (drive->device_type == IDE_CDROM) {
+ controller->current_command = value;
+ controller->error_register = 0;
+
+ controller->status.busy = 0;
+ controller->status.drive_ready = 1;
+ controller->status.write_fault = 0;
+ controller->status.drq = 1;
+ controller->status.err = 0;
+
+ controller->status.seek_complete = 1;
+ controller->status.corrected_data = 0;
+
+ controller->buffer_index = 0;
+ rd_raise_interrupt(dev, channel);
+ rd_identify_ATAPI_drive(dev, channel);
+ } else {
+ rd_command_aborted(dev, channel, 0xa1);
+ }
+ break;
+ }
+ case 0xa0: // SEND PACKET (atapi)
+ {
+ if (drive->device_type == IDE_CDROM) {
+ // PACKET
+
+ if (controller->features & (1 << 0)) {
+ PrintError("\t\tPACKET-DMA not supported");
+ return -1;
+ }
+
+ if (controller->features & (1 << 1)) {
+ PrintError("\t\tPACKET-overlapped not supported");
+ return -1;
+ }
+
+ // We're already ready!
+ controller->sector_count = 1;
+ controller->status.busy = 0;
+ controller->status.write_fault = 0;
+
+ // serv bit??
+ controller->status.drq = 1;
+ controller->status.err = 0;
+
+ // NOTE: no interrupt here
+ controller->current_command = value;
+ controller->buffer_index = 0;
+ } else {
+ rd_command_aborted (dev, channel, 0xa0);
+ }
+ break;
+ }
+ default:
+ PrintError("\t\tneed translate command %2x\n", value);
+ return -1;
+
+ }
+ return length;
+}
- // off_t logical_sector;
- // off_t ret;
+
+static int write_ctrl_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+ struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data);
+ struct channel_t * channel = NULL;
+ struct drive_t * master_drive = NULL;
+ struct drive_t * slave_drive = NULL;
+ struct controller_t * controller = NULL;
+ uchar_t value = *(uchar_t *)src;
rd_bool prev_control_reset;
- Bit32u id;
- int toc_length;
+ if (length != 1) {
+ PrintError("Invalid Status port read length: %d (port=%d)\n", length, port);
+ return -1;
+ }
+
+ if (is_primary_port(ramdisk, port)) {
+ channel = &(ramdisk->channels[0]);
+ } else if (is_secondary_port(ramdisk, port)) {
+ channel = &(ramdisk->channels[1]);
+ } else {
+ PrintError("Invalid Port: %d\n", port);
+ return -1;
+ }
+
+ master_drive = &(channel->drives[0]);
+ slave_drive = &(channel->drives[1]);
+
+ controller = &(get_selected_drive(channel)->controller);
+
+
+ PrintDebug("[write_control_handler] IO write at 0x%x, on drive %d/%d (val = 0x%x)\n",
+ port, get_channel_no(ramdisk, channel),
+ channel->drive_select,
+ value);
+
+ // (mch) Even if device 1 was selected, a write to this register
+ // goes to device 0 (if device 1 is absent)
+
+ prev_control_reset = controller->control.reset;
+
+ master_drive->controller.control.reset = value & 0x04;
+ slave_drive->controller.control.reset = value & 0x04;
+
+ // CGS: was: SELECTED_CONTROLLER(channel).control.disable_irq = value & 0x02;
+ master_drive->controller.control.disable_irq = value & 0x02;
+ slave_drive->controller.control.disable_irq = value & 0x02;
+
+ PrintDebug("\t\tadpater control reg: reset controller = %d\n",
+ (unsigned) (controller->control.reset) ? 1 : 0);
+ PrintDebug("\t\tadpater control reg: disable_irq(X) = %d\n",
+ (unsigned) (controller->control.disable_irq) ? 1 : 0);
+
+ if ((!prev_control_reset) && (controller->control.reset)) {
+ uint_t id = 0;
+
+ // transition from 0 to 1 causes all drives to reset
+ PrintDebug("\t\thard drive: RESET\n");
+
+ // (mch) Set BSY, drive not ready
+ for (id = 0; id < 2; id++) {
+ struct controller_t * ctrl = NULL;
+
+ if (id == 0) {
+ ctrl = &(master_drive->controller);
+ } else if (id == 1) {
+ ctrl = &(slave_drive->controller);
+ }
+
+ ctrl->status.busy = 1;
+ ctrl->status.drive_ready = 0;
+ ctrl->reset_in_progress = 1;
+
+ ctrl->status.write_fault = 0;
+ ctrl->status.seek_complete = 1;
+ ctrl->status.drq = 0;
+ ctrl->status.corrected_data = 0;
+ ctrl->status.err = 0;
+
+ ctrl->error_register = 0x01; // diagnostic code: no error
+
+ ctrl->current_command = 0x00;
+ ctrl->buffer_index = 0;
+
+ ctrl->sectors_per_block = 0x80;
+ ctrl->lba_mode = 0;
+
+ ctrl->control.disable_irq = 0;
+ }
- Bit8u channel = MAX_ATA_CHANNEL;
- Bit32u port = 0xff; // undefined
+ rd_lower_irq(dev, channel->irq);
- Ramdisk_Print("[rd_write_handler]\n");
- // Bit8u atapi_command;
- //int alloc_length;
+ } else if ((controller->reset_in_progress) &&
+ (!controller->control.reset)) {
+ uint_t id;
+ // Clear BSY and DRDY
+ PrintDebug("\t\tReset complete {%s}\n", device_type_to_str(get_selected_drive(channel)->device_type));
- for (channel=0; channel<MAX_ATA_CHANNEL; channel++) {
- if ((address & 0xfff8) == channels[channel].ioaddr1) {
- port = address - channels[channel].ioaddr1;
+ for (id = 0; id < 2; id++) {
+ struct controller_t * ctrl = NULL;
+ struct drive_t * drv = NULL;
+
+ if (id == 0) {
+ ctrl = &(master_drive->controller);
+ drv = master_drive;
+ } else if (id == 1) {
+ ctrl = &(slave_drive->controller);
+ drv = slave_drive;
+ }
+
+ ctrl->status.busy = 0;
+ ctrl->status.drive_ready = 1;
+ ctrl->reset_in_progress = 0;
+
+ // Device signature
+ if (drv->device_type == IDE_DISK) {
+ PrintDebug("\t\tdrive %d/%d is harddrive\n", get_channel_no(ramdisk, channel), id);
+ ctrl->head_no = 0;
+ ctrl->sector_count = 1;
+ ctrl->sector_no = 1;
+ ctrl->cylinder_no = 0;
+ } else {
+ ctrl->head_no = 0;
+ ctrl->sector_count = 1;
+ ctrl->sector_no = 1;
+ ctrl->cylinder_no = 0xeb14;
+ }
+ }
+ }
+
+ PrintDebug("\t\ts[0].controller.control.disable_irq = %02x\n",
+ master_drive->controller.control.disable_irq);
+ PrintDebug("\t\ts[1].controller.control.disable_irq = %02x\n",
+ slave_drive->controller.control.disable_irq);
+ return length;
+}
+
+
+static int read_general_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+ struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data);
+ struct channel_t * channel = NULL;
+ struct drive_t * drive = NULL;
+ struct controller_t * controller = NULL;
+
+
+ if (length != 1) {
+ PrintError("Invalid Status port read length: %d (port=%d)\n", length, port);
+ return -1;
+ }
+
+ if (is_primary_port(ramdisk, port)) {
+ channel = &(ramdisk->channels[0]);
+ } else if (is_secondary_port(ramdisk, port)) {
+ channel = &(ramdisk->channels[1]);
+ } else {
+ PrintError("Invalid Port: %d\n", port);
+ return -1;
+ }
+
+ drive = get_selected_drive(channel);
+ controller = &(drive->controller);
+
+
+ PrintDebug("[read_general_handler] IO read addr at %x, on drive %d/%d, curcmd = %02x\n",
+ port, get_channel_no(ramdisk, channel),
+ channel->drive_select,
+ controller->current_command);
+
+
+ switch (port) {
+ case PRI_FEATURES_PORT:
+ case SEC_FEATURES_PORT: // hard disk error register 0x1f1
+ {
+ uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->error_register;
+
+ controller->status.err = 0;
+
+ *(uchar_t *)dst = val;
+ return length;
+
break;
}
- else if ((address & 0xfff8) == channels[channel].ioaddr2) {
- port = address - channels[channel].ioaddr2 + 0x10;
+
+ case PRI_SECT_CNT_PORT:
+ case SEC_SECT_CNT_PORT: // hard disk sector count / interrupt reason 0x1f2
+ {
+ uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->sector_count;
+
+ *(uchar_t *)dst = val;
+ return length;
+
break;
- }
}
+ case PRI_SECT_ADDR1_PORT:
+ case SEC_SECT_ADDR1_PORT: // sector number 0x1f3
+ {
+ uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->sector_no;
+
+ *(uchar_t *)dst = val;
+ return length;
- if (channel == MAX_ATA_CHANNEL) {
- if (address != 0x03f6) {
- RD_PANIC("Panic: write: unable to find ATA channel, ioport=0x%04x\n", address);
- } else {
- channel = 0;
- port = address - 0x03e0;
+ break;
}
+
+ case PRI_SECT_ADDR2_PORT:
+ case SEC_SECT_ADDR2_PORT: // cylinder low 0x1f4
+ {
+ // -- WARNING : On real hardware the controller registers are shared between drives.
+ // So we must respond even if the select device is not present. Some OS uses this fact
+ // to detect the disks.... minix2 for example
+ uchar_t val = (num_drives_on_channel(channel) == 0) ? 0 : (controller->cylinder_no & 0x00ff);
+
+ *(uchar_t *)dst = val;
+ return length;
+
+ break;
}
- Ramdisk_Print("[W_handler] IO write to %x = %02x, channel = %d\n", (unsigned) address, (unsigned) value, channel);
+ case PRI_SECT_ADDR3_PORT:
+ case SEC_SECT_ADDR3_PORT: // cylinder high 0x1f5
+ {
+ // -- WARNING : On real hardware the controller registers are shared between drives.
+ // So we must respond even if the select device is not present. Some OS uses this fact
+ // to detect the disks.... minix2 for example
+ uchar_t val = (num_drives_on_channel(channel) == 0) ? 0 : (controller->cylinder_no >> 8);
- struct cdrom_interface *cdif = SELECTED_DRIVE(channel).cdrom.cd;
+ *(uchar_t *)dst = val;
+ return length;
- switch (port) {
+ break;
+ }
+ case PRI_DRV_SEL_PORT:
+ case SEC_DRV_SEL_PORT: // hard disk drive and head register 0x1f6
+ {
+ // b7 Extended data field for ECC
+ // b6/b5: Used to be sector size. 00=256,01=512,10=1024,11=128
+ // Since 512 was always used, bit 6 was taken to mean LBA mode:
+ // b6 1=LBA mode, 0=CHS mode
+ // b5 1
+ // b4: DRV
+ // b3..0 HD3..HD0
+ uchar_t val = ((1 << 7) |
+ ((controller->lba_mode > 0) << 6) |
+ (1 << 5) | // 01b = 512 sector size
+ (channel->drive_select << 4) |
+ (controller->head_no << 0));
+
+ *(uchar_t *)dst = val;
+ return length;
+
+ break;
+ }
+ case PRI_ADDR_REG_PORT:
+ case SEC_ADDR_REG_PORT: // Hard Disk Address Register 0x3f7
+ {
+ // Obsolete and unsupported register. Not driven by hard
+ // disk controller. Report all 1's. If floppy controller
+ // is handling this address, it will call this function
+ // set/clear D7 (the only bit it handles), then return
+ // the combined value
+ *(uchar_t *)dst = 0xff;
+ return length;
+ }
- case 0x00: // 0x1f0
- Ramdisk_Print("\t\twrite port 170\n");
+ default:
+ PrintError("Invalid Port: %d\n", port);
+ return -1;
+ }
+}
- //////////////////////////////////////////////////////////
- switch (SELECTED_CONTROLLER(channel).current_command) {
- case 0x30: // WRITE SECTORS
- RD_PANIC("\t\tneed to implement 0x30(write sector) to port 0x170\n");
+
+
+
+static int write_general_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+ struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data);
+ struct channel_t * channel = NULL;
+ struct drive_t * drive = NULL;
+ struct controller_t * controller = NULL;
+ uchar_t value = *(uchar_t *)src;
+
+ if (length != 1) {
+ PrintError("Invalid Status port read length: %d (port=%d)\n", length, port);
+ return -1;
+ }
+
+ if (is_primary_port(ramdisk, port)) {
+ channel = &(ramdisk->channels[0]);
+ } else if (is_secondary_port(ramdisk, port)) {
+ channel = &(ramdisk->channels[1]);
+ } else {
+ PrintError("Invalid Port: %d\n", port);
+ return -1;
+ }
+
+ drive = get_selected_drive(channel);
+ controller = &(drive->controller);
+
+
+ PrintDebug("[write_general_handler] IO write to port %x (val=0x%02x), channel = %d\n",
+ port, value, get_channel_no(ramdisk, channel));
+
+ switch (port) {
+
+ case PRI_FEATURES_PORT:
+ case SEC_FEATURES_PORT: // hard disk write precompensation 0x1f1
+ {
+ write_features(channel, value);
break;
+ }
+ case PRI_SECT_CNT_PORT:
+ case SEC_SECT_CNT_PORT: // hard disk sector count 0x1f2
+ {
+ write_sector_count(channel, value);
+ break;
+ }
+ case PRI_SECT_ADDR1_PORT:
+ case SEC_SECT_ADDR1_PORT: // hard disk sector number 0x1f3
+ {
+ write_sector_number(channel, value);
+ break;
+ }
+ case PRI_SECT_ADDR2_PORT:
+ case SEC_SECT_ADDR2_PORT: // hard disk cylinder low 0x1f4
+ {
+ write_cylinder_low(channel, value);
+ break;
+ }
+ case PRI_SECT_ADDR3_PORT:
+ case SEC_SECT_ADDR3_PORT: // hard disk cylinder high 0x1f5
+ {
+ write_cylinder_high(channel, value);
+ break;
+ }
+ case PRI_DRV_SEL_PORT:
+ case SEC_DRV_SEL_PORT: // hard disk drive and head register 0x1f6
+ {
+ // b7 Extended data field for ECC
+ // b6/b5: Used to be sector size. 00=256,01=512,10=1024,11=128
+ // Since 512 was always used, bit 6 was taken to mean LBA mode:
+ // b6 1=LBA mode, 0=CHS mode
+ // b5 1
+ // b4: DRV
+ // b3..0 HD3..HD0
+
+ // 1x1xxxxx
+
+ PrintDebug("\tDrive Select value=%x\n", value);
+
+ if ((value & 0xa0) != 0xa0) {
+ PrintDebug("\t\tIO write 0x%x (%02x): not 1x1xxxxxb\n", port, (unsigned) value);
+ }
+
+ write_head_no(channel, value & 0xf);
+ if ((controller->lba_mode == 0) && (((value >> 6) & 1) == 1)) {
+ PrintDebug("\t\tenabling LBA mode\n");
+ }
+
+ write_lba_mode(channel, (value >> 6) & 1);
+ drive->cdrom.cd->lba = (value >> 6) & 1;
- case 0xa0: // PACKET
- if (SELECTED_CONTROLLER(channel).buffer_index >= PACKET_SIZE)
- RD_PANIC("IO write(0x%04x): buffer_index >= PACKET_SIZE", address);
- SELECTED_CONTROLLER(channel).buffer[SELECTED_CONTROLLER(channel).buffer_index] = value;
- SELECTED_CONTROLLER(channel).buffer[SELECTED_CONTROLLER(channel).buffer_index+1] = (value >> 8);
- SELECTED_CONTROLLER(channel).buffer_index += 2;
- /* if packet completely writtten */
- if (SELECTED_CONTROLLER(channel).buffer_index >= PACKET_SIZE) {
- // complete command received
- Bit8u atapi_command = SELECTED_CONTROLLER(channel).buffer[0];
+ channel->drive_select = (value >> 4) & 0x01;
+ drive = get_selected_drive(channel);
+
+ if (drive->device_type == IDE_NONE) {
+ PrintDebug("\t\tError: device set to %d which does not exist! channel = 0x%x\n",
+ channel->drive_select, get_channel_no(ramdisk, channel));
+
+ controller->error_register = 0x04; // aborted
+ controller->status.err = 1;
+ }
+
+ break;
+ }
+ default:
+ PrintError("\t\thard drive: io write to unhandled port 0x%x (value = %c)\n", port, value);
+ //return -1;
+ }
+
+ return length;
+}
+
+
+
+
+
+static void rd_raise_interrupt(struct vm_device * dev, struct channel_t * channel) {
+ Bit32u irq;
+ // struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data);
+ struct drive_t * drive = get_selected_drive(channel);
+ struct controller_t * controller = &(drive->controller);
+
+ PrintDebug("[raise_interrupt] disable_irq = %02x\n", controller->control.disable_irq);
+
+ if (!(controller->control.disable_irq)) {
+ irq = channel->irq;
+
+ PrintDebug("\t\tRaising interrupt %d {%s}\n\n", irq, device_type_to_str(drive->device_type));
+
+ dev->vm->vm_ops.raise_irq(dev->vm, irq);
+ } else {
+ PrintDebug("\t\tirq is disabled\n");
+ }
+
+ return;
+}
+
+static void rd_lower_irq(struct vm_device *dev, Bit32u irq) // __attribute__(regparm(1))
+{
+ PrintDebug("[lower_irq] irq = %d\n", irq);
+ dev->vm->vm_ops.lower_irq(dev->vm, irq);
+}
+
+
+
+
+
+
+
+//////////////////////////////////////////////////////////////////////////
+
+/*
+ * ATAPI subroutines
+ */
+
+
+
+int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * channel, ushort_t value) {
+ //struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data);
+ struct drive_t * drive = get_selected_drive(channel);
+ struct controller_t * controller = &(drive->controller);
+
+ if (controller->buffer_index >= PACKET_SIZE) {
+ PrintError("ATAPI packet exceeded maximum length: buffer_index (%d) >= PACKET_SIZE\n",
+ controller->buffer_index);
+ return -1;
+ }
+
+ controller->buffer[controller->buffer_index] = value;
+ controller->buffer[controller->buffer_index + 1] = (value >> 8);
+ controller->buffer_index += 2;
+
+
+ /* if packet completely writtten */
+ if (controller->buffer_index >= PACKET_SIZE) {
+ // complete command received
+ Bit8u atapi_command = controller->buffer[0];
+
+ PrintDebug("\t\tcdrom: ATAPI command 0x%x started\n", atapi_command);
+
+ switch (atapi_command) {
+ case 0x00: // test unit ready
+ {
+ if (drive->cdrom.ready) {
+ rd_atapi_cmd_nop(dev, channel);
+ } else {
+ rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+ }
- Ramdisk_Print("\t\tcdrom: ATAPI command 0x%x started\n", atapi_command);
-
- switch (atapi_command) {
- case 0x00: // test unit ready
- if (SELECTED_DRIVE(channel).cdrom.ready) {
- rd_atapi_cmd_nop(channels, channel);
- } else {
- rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
- }
- rd_raise_interrupt(channels, channel);
- break;
-
- case 0x03: { // request sense
- int alloc_length = SELECTED_CONTROLLER(channel).buffer[4];
- rd_init_send_atapi_command(channels, channel, atapi_command, 18, alloc_length, false);
-
- // sense data
- SELECTED_CONTROLLER(channel).buffer[0] = 0x70 | (1 << 7);
- SELECTED_CONTROLLER(channel).buffer[1] = 0;
- SELECTED_CONTROLLER(channel).buffer[2] = SELECTED_DRIVE(channel).sense.sense_key;
- SELECTED_CONTROLLER(channel).buffer[3] = SELECTED_DRIVE(channel).sense.information.arr[0];
- SELECTED_CONTROLLER(channel).buffer[4] = SELECTED_DRIVE(channel).sense.information.arr[1];
- SELECTED_CONTROLLER(channel).buffer[5] = SELECTED_DRIVE(channel).sense.information.arr[2];
- SELECTED_CONTROLLER(channel).buffer[6] = SELECTED_DRIVE(channel).sense.information.arr[3];
- SELECTED_CONTROLLER(channel).buffer[7] = 17-7;
- SELECTED_CONTROLLER(channel).buffer[8] = SELECTED_DRIVE(channel).sense.specific_inf.arr[0];
- SELECTED_CONTROLLER(channel).buffer[9] = SELECTED_DRIVE(channel).sense.specific_inf.arr[1];
- SELECTED_CONTROLLER(channel).buffer[10] = SELECTED_DRIVE(channel).sense.specific_inf.arr[2];
- SELECTED_CONTROLLER(channel).buffer[11] = SELECTED_DRIVE(channel).sense.specific_inf.arr[3];
- SELECTED_CONTROLLER(channel).buffer[12] = SELECTED_DRIVE(channel).sense.asc;
- SELECTED_CONTROLLER(channel).buffer[13] = SELECTED_DRIVE(channel).sense.ascq;
- SELECTED_CONTROLLER(channel).buffer[14] = SELECTED_DRIVE(channel).sense.fruc;
- SELECTED_CONTROLLER(channel).buffer[15] = SELECTED_DRIVE(channel).sense.key_spec.arr[0];
- SELECTED_CONTROLLER(channel).buffer[16] = SELECTED_DRIVE(channel).sense.key_spec.arr[1];
- SELECTED_CONTROLLER(channel).buffer[17] = SELECTED_DRIVE(channel).sense.key_spec.arr[2];
-
- rd_ready_to_send_atapi(channels, channel);
+ rd_raise_interrupt(dev, channel);
+
+ break;
+ }
+ case 0x03: // request sense
+ {
+ int alloc_length = controller->buffer[4];
+
+ if (rd_init_send_atapi_command(dev, channel, atapi_command, 18, alloc_length, false) == -1) {
+ return -1;
}
- break;
+
+ // sense data
+ controller->buffer[0] = 0x70 | (1 << 7);
+ controller->buffer[1] = 0;
+ controller->buffer[2] = drive->sense.sense_key;
+ controller->buffer[3] = drive->sense.information.arr[0];
+ controller->buffer[4] = drive->sense.information.arr[1];
+ controller->buffer[5] = drive->sense.information.arr[2];
+ controller->buffer[6] = drive->sense.information.arr[3];
+ controller->buffer[7] = 17 - 7;
+ controller->buffer[8] = drive->sense.specific_inf.arr[0];
+ controller->buffer[9] = drive->sense.specific_inf.arr[1];
+ controller->buffer[10] = drive->sense.specific_inf.arr[2];
+ controller->buffer[11] = drive->sense.specific_inf.arr[3];
+ controller->buffer[12] = drive->sense.asc;
+ controller->buffer[13] = drive->sense.ascq;
+ controller->buffer[14] = drive->sense.fruc;
+ controller->buffer[15] = drive->sense.key_spec.arr[0];
+ controller->buffer[16] = drive->sense.key_spec.arr[1];
+ controller->buffer[17] = drive->sense.key_spec.arr[2];
+
+ rd_ready_to_send_atapi(dev, channel);
+ break;
+ }
+ case 0x1b: // start stop unit
+ {
+ //bx_bool Immed = (controller->buffer[1] >> 0) & 1;
+ rd_bool LoEj = (controller->buffer[4] >> 1) & 1;
+ rd_bool Start = (controller->buffer[4] >> 0) & 1;
+
+ // stop the disc
+ if ((!LoEj) && (!Start)) {
+ PrintError("FIXME: Stop disc not implemented\n");
+
+ rd_atapi_cmd_nop(dev, channel);
+ rd_raise_interrupt(dev, channel);
+ } else if (!LoEj && Start) { // start (spin up) the disc
+
+ drive->cdrom.cd->ops.start_cdrom(drive->cdrom.cd);
- case 0x1b: { // start stop unit
- //bx_bool Immed = (SELECTED_CONTROLLER(channel).buffer[1] >> 0) & 1;
- rd_bool LoEj = (SELECTED_CONTROLLER(channel).buffer[4] >> 1) & 1;
- rd_bool Start = (SELECTED_CONTROLLER(channel).buffer[4] >> 0) & 1;
+ PrintError("FIXME: ATAPI start disc not reading TOC\n");
+ rd_atapi_cmd_nop(dev, channel);
+ rd_raise_interrupt(dev, channel);
+ } else if (LoEj && !Start) { // Eject the disc
+ rd_atapi_cmd_nop(dev, channel);
- if (!LoEj && !Start) { // stop the disc
- RD_ERROR("FIXME: Stop disc not implemented\n");
- rd_atapi_cmd_nop(channels, channel);
- rd_raise_interrupt(channels, channel);
- } else if (!LoEj && Start) { // start (spin up) the disc
-
- SELECTED_DRIVE(channel).cdrom.cd->ops.start_cdrom(cdif);
-
- RD_ERROR("FIXME: ATAPI start disc not reading TOC\n");
- rd_atapi_cmd_nop(channels, channel);
- rd_raise_interrupt(channels, channel);
- } else if (LoEj && !Start) { // Eject the disc
- rd_atapi_cmd_nop(channels, channel);
+ if (drive->cdrom.ready) {
- if (SELECTED_DRIVE(channel).cdrom.ready) {
-
- SELECTED_DRIVE(channel).cdrom.cd->ops.eject_cdrom(cdif);
-
- SELECTED_DRIVE(channel).cdrom.ready = 0;
- //bx_options.atadevice[channel][SLAVE_SELECTED(channel)].Ostatus->set(EJECTED);
- //bx_gui->update_drive_status_buttons();
- }
- rd_raise_interrupt(channels, channel);
- } else { // Load the disc
- // My guess is that this command only closes the tray, that's a no-op for us
- rd_atapi_cmd_nop(channels, channel);
- rd_raise_interrupt(channels, channel);
+ drive->cdrom.cd->ops.eject_cdrom(drive->cdrom.cd);
+
+ drive->cdrom.ready = 0;
+ //bx_options.atadevice[channel][SLAVE_SELECTED(channel)].Ostatus->set(EJECTED);
+ //bx_gui->update_drive_status_buttons();
}
+ rd_raise_interrupt(dev, channel);
+ } else { // Load the disc
+ // My guess is that this command only closes the tray, that's a no-op for us
+ rd_atapi_cmd_nop(dev, channel);
+ rd_raise_interrupt(dev, channel);
}
- break;
-
- case 0xbd: { // mechanism status
- uint16 alloc_length = rd_read_16bit(SELECTED_CONTROLLER(channel).buffer + 8);
-
- if (alloc_length == 0)
- RD_PANIC("Zero allocation length to MECHANISM STATUS not impl.\n");
-
- rd_init_send_atapi_command(channels, channel, atapi_command, 8, alloc_length, false);
-
- SELECTED_CONTROLLER(channel).buffer[0] = 0; // reserved for non changers
- SELECTED_CONTROLLER(channel).buffer[1] = 0; // reserved for non changers
-
- SELECTED_CONTROLLER(channel).buffer[2] = 0; // Current LBA (TODO!)
- SELECTED_CONTROLLER(channel).buffer[3] = 0; // Current LBA (TODO!)
- SELECTED_CONTROLLER(channel).buffer[4] = 0; // Current LBA (TODO!)
-
- SELECTED_CONTROLLER(channel).buffer[5] = 1; // one slot
-
- SELECTED_CONTROLLER(channel).buffer[6] = 0; // slot table length
- SELECTED_CONTROLLER(channel).buffer[7] = 0; // slot table length
-
- rd_ready_to_send_atapi(channels, channel);
+ break;
+ }
+ case 0xbd: // mechanism status
+ {
+ uint16_t alloc_length = rd_read_16bit(controller->buffer + 8);
+
+ if (alloc_length == 0) {
+ PrintError("Zero allocation length to MECHANISM STATUS not impl.\n");
+ return -1;
}
- break;
-
- case 0x5a: { // mode sense
- uint16 alloc_length = rd_read_16bit(SELECTED_CONTROLLER(channel).buffer + 7);
-
- Bit8u PC = SELECTED_CONTROLLER(channel).buffer[2] >> 6;
- Bit8u PageCode = SELECTED_CONTROLLER(channel).buffer[2] & 0x3f;
-
- switch (PC) {
- case 0x0: // current values
+
+ if (rd_init_send_atapi_command(dev, channel, atapi_command, 8, alloc_length, false) == -1) {
+ return -1;
+ }
+
+ controller->buffer[0] = 0; // reserved for non changers
+ controller->buffer[1] = 0; // reserved for non changers
+
+ controller->buffer[2] = 0; // Current LBA (TODO!)
+ controller->buffer[3] = 0; // Current LBA (TODO!)
+ controller->buffer[4] = 0; // Current LBA (TODO!)
+
+ controller->buffer[5] = 1; // one slot
+
+ controller->buffer[6] = 0; // slot table length
+ controller->buffer[7] = 0; // slot table length
+
+ rd_ready_to_send_atapi(dev, channel);
+ break;
+ }
+ case 0x5a: // mode sense
+ {
+ uint16_t alloc_length = rd_read_16bit(controller->buffer + 7);
+
+ Bit8u PC = controller->buffer[2] >> 6;
+ Bit8u PageCode = controller->buffer[2] & 0x3f;
+
+ switch (PC) {
+ case 0x0: // current values
+ {
switch (PageCode) {
case 0x01: // error recovery
- rd_init_send_atapi_command(channels, channel, atapi_command, sizeof(struct error_recovery_t) + 8, alloc_length, false);
-
- rd_init_mode_sense_single(channels, channel, &SELECTED_DRIVE(channel).cdrom.current.error_recovery,
- sizeof(struct error_recovery_t));
- rd_ready_to_send_atapi(channels, channel);
- break;
-
+ {
+
+ if (rd_init_send_atapi_command(dev, channel, atapi_command, sizeof(struct error_recovery_t) + 8, alloc_length, false) == -1) {
+ return -1;
+ }
+
+ rd_init_mode_sense_single(dev, channel, &(drive->cdrom.current.error_recovery),
+ sizeof(struct error_recovery_t));
+ rd_ready_to_send_atapi(dev, channel);
+ break;
+ }
case 0x2a: // CD-ROM capabilities & mech. status
- rd_init_send_atapi_command(channels, channel, atapi_command, 28, alloc_length, false);
- rd_init_mode_sense_single(channels, channel, &SELECTED_CONTROLLER(channel).buffer[8], 28);
- SELECTED_CONTROLLER(channel).buffer[8] = 0x2a;
- SELECTED_CONTROLLER(channel).buffer[9] = 0x12;
- SELECTED_CONTROLLER(channel).buffer[10] = 0x00;
- SELECTED_CONTROLLER(channel).buffer[11] = 0x00;
- // Multisession, Mode 2 Form 2, Mode 2 Form 1
- SELECTED_CONTROLLER(channel).buffer[12] = 0x70;
- SELECTED_CONTROLLER(channel).buffer[13] = (3 << 5);
- SELECTED_CONTROLLER(channel).buffer[14] = (unsigned char)
- (1 |
- (SELECTED_DRIVE(channel).cdrom.locked ? (1 << 1) : 0) |
- (1 << 3) |
- (1 << 5));
- SELECTED_CONTROLLER(channel).buffer[15] = 0x00;
- SELECTED_CONTROLLER(channel).buffer[16] = (706 >> 8) & 0xff;
- SELECTED_CONTROLLER(channel).buffer[17] = 706 & 0xff;
- SELECTED_CONTROLLER(channel).buffer[18] = 0;
- SELECTED_CONTROLLER(channel).buffer[19] = 2;
- SELECTED_CONTROLLER(channel).buffer[20] = (512 >> 8) & 0xff;
- SELECTED_CONTROLLER(channel).buffer[21] = 512 & 0xff;
- SELECTED_CONTROLLER(channel).buffer[22] = (706 >> 8) & 0xff;
- SELECTED_CONTROLLER(channel).buffer[23] = 706 & 0xff;
- SELECTED_CONTROLLER(channel).buffer[24] = 0;
- SELECTED_CONTROLLER(channel).buffer[25] = 0;
- SELECTED_CONTROLLER(channel).buffer[26] = 0;
- SELECTED_CONTROLLER(channel).buffer[27] = 0;
- rd_ready_to_send_atapi(channels, channel);
- break;
-
+ {
+
+ if (rd_init_send_atapi_command(dev, channel, atapi_command, 28, alloc_length, false) == -1) {
+ return -1;
+ }
+
+ rd_init_mode_sense_single(dev, channel, &(controller->buffer[8]), 28);
+
+ controller->buffer[8] = 0x2a;
+ controller->buffer[9] = 0x12;
+ controller->buffer[10] = 0x00;
+ controller->buffer[11] = 0x00;
+ // Multisession, Mode 2 Form 2, Mode 2 Form 1
+ controller->buffer[12] = 0x70;
+ controller->buffer[13] = (3 << 5);
+ controller->buffer[14] = (unsigned char) (1 |
+ (drive->cdrom.locked ? (1 << 1) : 0) |
+ (1 << 3) |
+ (1 << 5));
+ controller->buffer[15] = 0x00;
+ controller->buffer[16] = (706 >> 8) & 0xff;
+ controller->buffer[17] = 706 & 0xff;
+ controller->buffer[18] = 0;
+ controller->buffer[19] = 2;
+ controller->buffer[20] = (512 >> 8) & 0xff;
+ controller->buffer[21] = 512 & 0xff;
+ controller->buffer[22] = (706 >> 8) & 0xff;
+ controller->buffer[23] = 706 & 0xff;
+ controller->buffer[24] = 0;
+ controller->buffer[25] = 0;
+ controller->buffer[26] = 0;
+ controller->buffer[27] = 0;
+ rd_ready_to_send_atapi(dev, channel);
+ break;
+ }
case 0x0d: // CD-ROM
case 0x0e: // CD-ROM audio control
case 0x3f: // all
- RD_ERROR("cdrom: MODE SENSE (curr), code=%x not implemented yet\n",
- PageCode);
- rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- rd_raise_interrupt(channels, channel);
- break;
-
- default:
- // not implemeted by this device
- Ramdisk_Print("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
- PC, PageCode);
- rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- rd_raise_interrupt(channels, channel);
+ {
+ PrintError("Ramdisk: cdrom: MODE SENSE (curr), code=%x not implemented yet\n",
+ PageCode);
+ rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
+ ASC_INV_FIELD_IN_CMD_PACKET);
+ rd_raise_interrupt(dev, channel);
+ break;
+ }
+ default:
+ {
+ // not implemeted by this device
+ PrintDebug("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
+ PC, PageCode);
+ rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
+ ASC_INV_FIELD_IN_CMD_PACKET);
+ rd_raise_interrupt(dev, channel);
+ break;
+ }
+ }
break;
}
- break;
-
- case 0x1: // changeable values
+ case 0x1: // changeable values
+ {
switch (PageCode) {
case 0x01: // error recovery
case 0x0d: // CD-ROM
case 0x0e: // CD-ROM audio control
case 0x2a: // CD-ROM capabilities & mech. status
case 0x3f: // all
- RD_ERROR("cdrom: MODE SENSE (chg), code=%x not implemented yet\n",
- PageCode);
- rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- rd_raise_interrupt(channels, channel);
+ {
+ PrintError("cdrom: MODE SENSE (chg), code=%x not implemented yet\n",
+ PageCode);
+ rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
+ ASC_INV_FIELD_IN_CMD_PACKET);
+ rd_raise_interrupt(dev, channel);
+ break;
+ }
+ default:
+ {
+ // not implemeted by this device
+ PrintDebug("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
+ PC, PageCode);
+ rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
+ ASC_INV_FIELD_IN_CMD_PACKET);
+ rd_raise_interrupt(dev, channel);
+ break;
+ }
+ }
break;
-
- default:
- // not implemeted by this device
- Ramdisk_Print("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
- PC, PageCode);
- rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- rd_raise_interrupt(channels, channel);
- break;
- }
- break;
-
+ }
case 0x2: // default values
- switch (PageCode) {
- case 0x01: // error recovery
- case 0x0d: // CD-ROM
- case 0x0e: // CD-ROM audio control
- case 0x2a: // CD-ROM capabilities & mech. status
- case 0x3f: // all
- RD_PANIC("cdrom: MODE SENSE (dflt), code=%x\n",
- PageCode);
- break;
-
+ {
+ switch (PageCode) {
+ case 0x01: // error recovery
+ case 0x0d: // CD-ROM
+ case 0x0e: // CD-ROM audio control
+ case 0x2a: // CD-ROM capabilities & mech. status
+ case 0x3f: // all
+ PrintError("cdrom: MODE SENSE (dflt), code=%x\n",
+ PageCode);
+ return -1;
+
default:
- // not implemeted by this device
- Ramdisk_Print("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
- PC, PageCode);
- rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- rd_raise_interrupt(channels, channel);
- break;
+ {
+ // not implemeted by this device
+ PrintDebug("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
+ PC, PageCode);
+ rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
+ ASC_INV_FIELD_IN_CMD_PACKET);
+ rd_raise_interrupt(dev, channel);
+ break;
+ }
+ }
+ break;
}
- break;
-
case 0x3: // saved values not implemented
- rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST, ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
- rd_raise_interrupt(channels, channel);
- break;
-
+ {
+ rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
+ rd_raise_interrupt(dev, channel);
+ break;
+ }
default:
- RD_PANIC("Should not get here!\n");
- break;
+ {
+ PrintError("Should not get here!\n");
+ return -1;
+ break;
+ }
}
+ break;
}
- break;
-
- case 0x12: { // inquiry
- uint8 alloc_length = SELECTED_CONTROLLER(channel).buffer[4];
-
- rd_init_send_atapi_command(channels, channel, atapi_command, 36, alloc_length, false);
-
- SELECTED_CONTROLLER(channel).buffer[0] = 0x05; // CD-ROM
- SELECTED_CONTROLLER(channel).buffer[1] = 0x80; // Removable
- SELECTED_CONTROLLER(channel).buffer[2] = 0x00; // ISO, ECMA, ANSI version
- SELECTED_CONTROLLER(channel).buffer[3] = 0x21; // ATAPI-2, as specified
- SELECTED_CONTROLLER(channel).buffer[4] = 31; // additional length (total 36)
- SELECTED_CONTROLLER(channel).buffer[5] = 0x00; // reserved
- SELECTED_CONTROLLER(channel).buffer[6] = 0x00; // reserved
- SELECTED_CONTROLLER(channel).buffer[7] = 0x00; // reserved
-
- // Vendor ID
- const char* vendor_id = "VTAB ";
- int i;
- for (i = 0; i < 8; i++)
- SELECTED_CONTROLLER(channel).buffer[8+i] = vendor_id[i];
-
- // Product ID
- const char* product_id = "Turbo CD-ROM ";
- for (i = 0; i < 16; i++)
- SELECTED_CONTROLLER(channel).buffer[16+i] = product_id[i];
-
- // Product Revision level
- const char* rev_level = "1.0 ";
- for (i = 0; i < 4; i++)
- SELECTED_CONTROLLER(channel).buffer[32+i] = rev_level[i];
-
- rd_ready_to_send_atapi(channels, channel);
- }
- break;
-
- case 0x25: { // read cd-rom capacity
- // no allocation length???
- rd_init_send_atapi_command(channels, channel, atapi_command, 8, 8, false);
-
- if (SELECTED_DRIVE(channel).cdrom.ready) {
- uint32 capacity = SELECTED_DRIVE(channel).cdrom.capacity;
- Ramdisk_Print("\t\tCapacity is %d sectors (%d bytes)\n", capacity, capacity * 2048);
- SELECTED_CONTROLLER(channel).buffer[0] = (capacity >> 24) & 0xff;
- SELECTED_CONTROLLER(channel).buffer[1] = (capacity >> 16) & 0xff;
- SELECTED_CONTROLLER(channel).buffer[2] = (capacity >> 8) & 0xff;
- SELECTED_CONTROLLER(channel).buffer[3] = (capacity >> 0) & 0xff;
- SELECTED_CONTROLLER(channel).buffer[4] = (2048 >> 24) & 0xff;
- SELECTED_CONTROLLER(channel).buffer[5] = (2048 >> 16) & 0xff;
- SELECTED_CONTROLLER(channel).buffer[6] = (2048 >> 8) & 0xff;
- SELECTED_CONTROLLER(channel).buffer[7] = (2048 >> 0) & 0xff;
- rd_ready_to_send_atapi(channels, channel);
- } else {
- rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
- rd_raise_interrupt(channels, channel);
- }
+ case 0x12: // inquiry
+ {
+ uint8_t alloc_length = controller->buffer[4];
+
+ if (rd_init_send_atapi_command(dev, channel, atapi_command, 36, alloc_length, false) == -1) {
+ return -1;
}
- break;
-
- case 0xbe: { // read cd
- if (SELECTED_DRIVE(channel).cdrom.ready) {
- RD_ERROR("Read CD with CD present not implemented\n");
- rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
- rd_raise_interrupt(channels, channel);
- } else {
- rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
- rd_raise_interrupt(channels, channel);
- }
+
+ controller->buffer[0] = 0x05; // CD-ROM
+ controller->buffer[1] = 0x80; // Removable
+ controller->buffer[2] = 0x00; // ISO, ECMA, ANSI version
+ controller->buffer[3] = 0x21; // ATAPI-2, as specified
+ controller->buffer[4] = 31; // additional length (total 36)
+ controller->buffer[5] = 0x00; // reserved
+ controller->buffer[6] = 0x00; // reserved
+ controller->buffer[7] = 0x00; // reserved
+
+ // Vendor ID
+ const char* vendor_id = "VTAB ";
+ int i;
+ for (i = 0; i < 8; i++) {
+ controller->buffer[8+i] = vendor_id[i];
}
- break;
-
- case 0x43: { // read toc
- if (SELECTED_DRIVE(channel).cdrom.ready) {
-
- bool msf = (SELECTED_CONTROLLER(channel).buffer[1] >> 1) & 1;
- uint8 starting_track = SELECTED_CONTROLLER(channel).buffer[6];
-
- uint16 alloc_length = rd_read_16bit(SELECTED_CONTROLLER(channel).buffer + 7);
-
- uint8 format = (SELECTED_CONTROLLER(channel).buffer[9] >> 6);
- int i;
- switch (format) {
- case 0:
-
- if (!(SELECTED_DRIVE(channel).cdrom.cd->ops.read_toc(cdif, SELECTED_CONTROLLER(channel).buffer,
- &toc_length, msf, starting_track))) {
- rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- rd_raise_interrupt(channels, channel);
- } else {
- rd_init_send_atapi_command(channels, channel, atapi_command, toc_length, alloc_length, false);
- rd_ready_to_send_atapi(channels, channel);
- }
- break;
-
- case 1:
- // multi session stuff. we ignore this and emulate a single session only
- rd_init_send_atapi_command(channels, channel, atapi_command, 12, alloc_length, false);
-
- SELECTED_CONTROLLER(channel).buffer[0] = 0;
- SELECTED_CONTROLLER(channel).buffer[1] = 0x0a;
- SELECTED_CONTROLLER(channel).buffer[2] = 1;
- SELECTED_CONTROLLER(channel).buffer[3] = 1;
- for (i = 0; i < 8; i++)
- SELECTED_CONTROLLER(channel).buffer[4+i] = 0;
-
- rd_ready_to_send_atapi(channels, channel);
- break;
-
- case 2:
- default:
- RD_PANIC("(READ TOC) Format %d not supported\n", format);
- break;
- }
- } else {
- rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
- rd_raise_interrupt(channels, channel);
- }
+
+ // Product ID
+ const char* product_id = "Turbo CD-ROM ";
+ for (i = 0; i < 16; i++) {
+ controller->buffer[16+i] = product_id[i];
+ }
+
+ // Product Revision level
+ const char* rev_level = "1.0 ";
+ for (i = 0; i < 4; i++) {
+ controller->buffer[32 + i] = rev_level[i];
+ }
+
+ rd_ready_to_send_atapi(dev, channel);
+ break;
+ }
+ case 0x25: // read cd-rom capacity
+ {
+ // no allocation length???
+ if (rd_init_send_atapi_command(dev, channel, atapi_command, 8, 8, false) == -1) {
+ return -1;
}
- break;
-
- case 0x28: // read (10)
- case 0xa8: // read (12)
- {
- uint32 transfer_length;
- if (atapi_command == 0x28)
- transfer_length = rd_read_16bit(SELECTED_CONTROLLER(channel).buffer + 7);
- else
- transfer_length = rd_read_32bit(SELECTED_CONTROLLER(channel).buffer + 6);
-
- uint32 lba = rd_read_32bit(SELECTED_CONTROLLER(channel).buffer + 2);
+ if (drive->cdrom.ready) {
+ uint32_t capacity = drive->cdrom.capacity;
+
+ PrintDebug("\t\tCapacity is %d sectors (%d bytes)\n", capacity, capacity * 2048);
+
+ controller->buffer[0] = (capacity >> 24) & 0xff;
+ controller->buffer[1] = (capacity >> 16) & 0xff;
+ controller->buffer[2] = (capacity >> 8) & 0xff;
+ controller->buffer[3] = (capacity >> 0) & 0xff;
+ controller->buffer[4] = (2048 >> 24) & 0xff;
+ controller->buffer[5] = (2048 >> 16) & 0xff;
+ controller->buffer[6] = (2048 >> 8) & 0xff;
+ controller->buffer[7] = (2048 >> 0) & 0xff;
+
+ rd_ready_to_send_atapi(dev, channel);
+ } else {
+ rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+ rd_raise_interrupt(dev, channel);
+ }
+ break;
+ }
+
+
+ case 0xbe: // read cd
+ {
+ if (drive->cdrom.ready) {
+ PrintError("Read CD with CD present not implemented\n");
+ rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
+ rd_raise_interrupt(dev, channel);
+ } else {
+ rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+ rd_raise_interrupt(dev, channel);
+ }
+ break;
+ }
+ case 0x43: // read toc
+ {
+ if (drive->cdrom.ready) {
+ int toc_length;
+ bool msf = (controller->buffer[1] >> 1) & 1;
+ uint8_t starting_track = controller->buffer[6];
+
+ uint16_t alloc_length = rd_read_16bit(controller->buffer + 7);
+
+ uint8_t format = (controller->buffer[9] >> 6);
+ int i;
+ switch (format) {
+ case 0:
- if (!SELECTED_DRIVE(channel).cdrom.ready) {
- rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
- rd_raise_interrupt(channels, channel);
- break;
+ if (!(drive->cdrom.cd->ops.read_toc(drive->cdrom.cd, controller->buffer,
+ &toc_length, msf, starting_track))) {
+ rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
+ ASC_INV_FIELD_IN_CMD_PACKET);
+ rd_raise_interrupt(dev, channel);
+ } else {
+ if (rd_init_send_atapi_command(dev, channel, atapi_command, toc_length, alloc_length, false) == -1) {
+ return -1;
+ }
+ rd_ready_to_send_atapi(dev, channel);
}
+ break;
- if (transfer_length == 0) {
- rd_atapi_cmd_nop(channels, channel);
- rd_raise_interrupt(channels, channel);
- Ramdisk_Print("\t\tREAD(%d) with transfer length 0, ok\n", atapi_command==0x28?10:12);
- break;
+ case 1:
+ // multi session stuff. we ignore this and emulate a single session only
+ if (rd_init_send_atapi_command(dev, channel, atapi_command, 12, alloc_length, false) == -1) {
+ return -1;
}
- if (lba + transfer_length > SELECTED_DRIVE(channel).cdrom.capacity) {
- rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
- rd_raise_interrupt(channels, channel);
- break;
+ controller->buffer[0] = 0;
+ controller->buffer[1] = 0x0a;
+ controller->buffer[2] = 1;
+ controller->buffer[3] = 1;
+
+ for (i = 0; i < 8; i++) {
+ controller->buffer[4 + i] = 0;
}
-
- Ramdisk_Print("\t\tcdrom: READ (%d) LBA=%d LEN=%d\n", atapi_command==0x28?10:12, lba, transfer_length);
-
- // handle command
- rd_init_send_atapi_command(channels, channel, atapi_command, transfer_length * 2048,
- transfer_length * 2048, true);
- SELECTED_DRIVE(channel).cdrom.remaining_blocks = transfer_length;
- SELECTED_DRIVE(channel).cdrom.next_lba = lba;
- rd_ready_to_send_atapi(channels, channel);
- }
- break;
-
- case 0x2b: { // seek
- uint32 lba = rd_read_32bit(SELECTED_CONTROLLER(channel).buffer + 2);
- if (!SELECTED_DRIVE(channel).cdrom.ready) {
- rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
- rd_raise_interrupt(channels, channel);
- break;
- }
-
- if (lba > SELECTED_DRIVE(channel).cdrom.capacity) {
- rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
- rd_raise_interrupt(channels, channel);
+
+ rd_ready_to_send_atapi(dev, channel);
break;
+
+ case 2:
+ default:
+ PrintError("(READ TOC) Format %d not supported\n", format);
+ return -1;
}
- Ramdisk_Print("\t\tcdrom: SEEK (ignored)\n");
- rd_atapi_cmd_nop(channels, channel);
- rd_raise_interrupt(channels, channel);
+ } else {
+ rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+ rd_raise_interrupt(dev, channel);
+ }
+ break;
+ }
+ case 0x28: // read (10)
+ case 0xa8: // read (12)
+ {
+
+ uint32_t transfer_length;
+ if (atapi_command == 0x28) {
+ transfer_length = rd_read_16bit(controller->buffer + 7);
+ } else {
+ transfer_length = rd_read_32bit(controller->buffer + 6);
}
+
+ uint32_t lba = rd_read_32bit(controller->buffer + 2);
+
+ if (!(drive->cdrom.ready)) {
+ rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+ rd_raise_interrupt(dev, channel);
break;
-
- case 0x1e: { // prevent/allow medium removal
- if (SELECTED_DRIVE(channel).cdrom.ready) {
- SELECTED_DRIVE(channel).cdrom.locked = SELECTED_CONTROLLER(channel).buffer[4] & 1;
- rd_atapi_cmd_nop(channels, channel);
- } else {
- rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
- }
- rd_raise_interrupt(channels, channel);
}
+
+ if (transfer_length == 0) {
+ rd_atapi_cmd_nop(dev, channel);
+ rd_raise_interrupt(dev, channel);
+ PrintDebug("\t\tREAD(%d) with transfer length 0, ok\n", (atapi_command == 0x28) ? 10 : 12);
break;
-
- case 0x42: { // read sub-channel
- bool msf = get_packet_field(channel,1, 1, 1);
- bool sub_q = get_packet_field(channel,2, 6, 1);
- uint8 data_format = get_packet_byte(channel,3);
- uint8 track_number = get_packet_byte(channel,6);
- uint16 alloc_length = get_packet_word(channel,7);
- UNUSED(msf);
- UNUSED(data_format);
- UNUSED(track_number);
-
- if (!SELECTED_DRIVE(channel).cdrom.ready) {
- rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
- rd_raise_interrupt(channels, channel);
- } else {
- SELECTED_CONTROLLER(channel).buffer[0] = 0;
- SELECTED_CONTROLLER(channel).buffer[1] = 0; // audio not supported
- SELECTED_CONTROLLER(channel).buffer[2] = 0;
- SELECTED_CONTROLLER(channel).buffer[3] = 0;
+ }
- int ret_len = 4; // header size
+ if (lba + transfer_length > drive->cdrom.capacity) {
+ rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
+ rd_raise_interrupt(dev, channel);
+ break;
+ }
- if (sub_q) { // !sub_q == header only
- RD_ERROR("Read sub-channel with SubQ not implemented\n");
- rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- rd_raise_interrupt(channels, channel);
- }
+ PrintDebug("\t\tcdrom: READ (%d) LBA=%d LEN=%d\n",
+ (atapi_command == 0x28) ? 10 : 12,
+ lba, transfer_length);
- rd_init_send_atapi_command(channels, channel, atapi_command, ret_len, alloc_length, false);
- rd_ready_to_send_atapi(channels, channel);
- }
+ // handle command
+ if (rd_init_send_atapi_command(dev, channel, atapi_command, transfer_length * 2048,
+ transfer_length * 2048, true) == -1) {
+ return -1;
}
+ drive->cdrom.remaining_blocks = transfer_length;
+ drive->cdrom.next_lba = lba;
+ rd_ready_to_send_atapi(dev, channel);
+ break;
+ }
+ case 0x2b: // seek
+ {
+ uint32_t lba = rd_read_32bit(controller->buffer + 2);
+
+ if (!(drive->cdrom.ready)) {
+ rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+ rd_raise_interrupt(dev, channel);
break;
-
- case 0x51: { // read disc info
- // no-op to keep the Linux CD-ROM driver happy
- rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
- rd_raise_interrupt(channels, channel);
}
- break;
-
- case 0x55: // mode select
- case 0xa6: // load/unload cd
- case 0x4b: // pause/resume
- case 0x45: // play audio
- case 0x47: // play audio msf
- case 0xbc: // play cd
- case 0xb9: // read cd msf
- case 0x44: // read header
- case 0xba: // scan
- case 0xbb: // set cd speed
- case 0x4e: // stop play/scan
- case 0x46: // ???
- case 0x4a: // ???
- RD_ERROR("ATAPI command 0x%x not implemented yet\n",
- atapi_command);
- rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
- rd_raise_interrupt(channels, channel);
- break;
- default:
- RD_PANIC("Unknown ATAPI command 0x%x (%d)\n",
- atapi_command, atapi_command);
- // We'd better signal the error if the user chose to continue
- rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
- rd_raise_interrupt(channels, channel);
+
+ if (lba > drive->cdrom.capacity) {
+ rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
+ rd_raise_interrupt(dev, channel);
break;
}
- }
-
- break;
-
-
- default:
- RD_PANIC("\t\tIO write(0x%x): current command is %02xh\n", address,
- (unsigned) SELECTED_CONTROLLER(channel).current_command);
- }
+
+ PrintDebug("\t\tcdrom: SEEK (ignored)\n");
-/////////////////////////////////////////////////////////
- break;
- case 0x01: // hard disk write precompensation 0x1f1
- WRITE_FEATURES(channel,value);
- break;
+ rd_atapi_cmd_nop(dev, channel);
+ rd_raise_interrupt(dev, channel);
- case 0x02: // hard disk sector count 0x1f2
- WRITE_SECTOR_COUNT(channel,value);
- break;
-
- case 0x03: // hard disk sector number 0x1f3
- WRITE_SECTOR_NUMBER(channel,value);
- break;
-
- case 0x04: // hard disk cylinder low 0x1f4
- WRITE_CYLINDER_LOW(channel,value);
- break;
-
- case 0x05: // hard disk cylinder high 0x1f5
- WRITE_CYLINDER_HIGH(channel,value);
- break;
-
- case 0x06: // hard disk drive and head register 0x1f6
- // b7 Extended data field for ECC
- // b6/b5: Used to be sector size. 00=256,01=512,10=1024,11=128
- // Since 512 was always used, bit 6 was taken to mean LBA mode:
- // b6 1=LBA mode, 0=CHS mode
- // b5 1
- // b4: DRV
- // b3..0 HD3..HD0
-
- if ( (value & 0xa0) != 0xa0 ) // 1x1xxxxx
- Ramdisk_Print("\t\tIO write 0x%x (%02x): not 1x1xxxxxb\n", address, (unsigned) value);
-
- Bit32u drvsel = channels[channel].drive_select = (value >> 4) & 0x01;
- WRITE_HEAD_NO(channel,value & 0xf);
- if (SELECTED_CONTROLLER(channel).lba_mode == 0 && ((value >> 6) & 1) == 1){
- Ramdisk_Print("\t\tenabling LBA mode\n");
+ break;
+ }
+ case 0x1e: // prevent/allow medium removal
+ {
+
+ if (drive->cdrom.ready) {
+ drive->cdrom.locked = controller->buffer[4] & 1;
+ rd_atapi_cmd_nop(dev, channel);
+ } else {
+ rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
}
- WRITE_LBA_MODE(channel,(value >> 6) & 1);
- SELECTED_DRIVE(channel).cdrom.cd->lba = (value >> 6) & 1;
-
-
- if (!SELECTED_IS_PRESENT(channel)) {
- Ramdisk_Print ("\t\tError: device set to %d which does not exist! channel = %d\n",drvsel, channel);
- SELECTED_CONTROLLER(channel).error_register = 0x04; // aborted
- SELECTED_CONTROLLER(channel).status.err = 1;
- }
-
- break;
-
-
- case 0x07: // hard disk command 0x1f7
-
- switch (value) {
- // ATAPI commands
- case 0xa1: // IDENTIFY PACKET DEVICE
- if (SELECTED_IS_CD(channel)) {
- SELECTED_CONTROLLER(channel).current_command = value;
- SELECTED_CONTROLLER(channel).error_register = 0;
-
- SELECTED_CONTROLLER(channel).status.busy = 0;
- SELECTED_CONTROLLER(channel).status.drive_ready = 1;
- SELECTED_CONTROLLER(channel).status.write_fault = 0;
- SELECTED_CONTROLLER(channel).status.drq = 1;
- SELECTED_CONTROLLER(channel).status.err = 0;
-
- SELECTED_CONTROLLER(channel).status.seek_complete = 1;
- SELECTED_CONTROLLER(channel).status.corrected_data = 0;
-
- SELECTED_CONTROLLER(channel).buffer_index = 0;
- rd_raise_interrupt(channels, channel);
- rd_identify_ATAPI_drive(channels, channel);
- } else {
- rd_command_aborted(channels, channel, 0xa1);
- }
- break;
-
- case 0xa0: // SEND PACKET (atapi)
- if (SELECTED_IS_CD(channel)) {
- // PACKET
- if (SELECTED_CONTROLLER(channel).features & (1 << 0))
- RD_PANIC("\t\tPACKET-DMA not supported");
- if (SELECTED_CONTROLLER(channel).features & (1 << 1))
- RD_PANIC("\t\tPACKET-overlapped not supported");
-
- // We're already ready!
- SELECTED_CONTROLLER(channel).sector_count = 1;
- SELECTED_CONTROLLER(channel).status.busy = 0;
- SELECTED_CONTROLLER(channel).status.write_fault = 0;
- // serv bit??
- SELECTED_CONTROLLER(channel).status.drq = 1;
- SELECTED_CONTROLLER(channel).status.err = 0;
-
- // NOTE: no interrupt here
- SELECTED_CONTROLLER(channel).current_command = value;
- SELECTED_CONTROLLER(channel).buffer_index = 0;
- } else {
- rd_command_aborted (channels, channel, 0xa0);
- }
- break;
- default:
- Ramdisk_Print("\t\tneed translate command %2x\n", value);
- break;
- }//switch(value)
+ rd_raise_interrupt(dev, channel);
-
- case 0x16: // hard disk adapter control 0x3f6
- // (mch) Even if device 1 was selected, a write to this register
- // goes to device 0 (if device 1 is absent)
-
- prev_control_reset = SELECTED_CONTROLLER(channel).control.reset;
- channels[channel].drives[0].controller.control.reset = value & 0x04;
- channels[channel].drives[1].controller.control.reset = value & 0x04;
- // CGS: was: SELECTED_CONTROLLER(channel).control.disable_irq = value & 0x02;
- channels[channel].drives[0].controller.control.disable_irq = value & 0x02;
- channels[channel].drives[1].controller.control.disable_irq = value & 0x02;
-
- Ramdisk_Print("\t\tadpater control reg: reset controller = %d\n",
- (unsigned) (SELECTED_CONTROLLER(channel).control.reset) ? 1 : 0);
- Ramdisk_Print("\t\tadpater control reg: disable_irq(X) = %d\n",
- (unsigned) (SELECTED_CONTROLLER(channel).control.disable_irq) ? 1 : 0);
-
- if (!prev_control_reset && SELECTED_CONTROLLER(channel).control.reset) {
- // transition from 0 to 1 causes all drives to reset
- Ramdisk_Print("\t\thard drive: RESET\n");
-
- // (mch) Set BSY, drive not ready
- for (id = 0; id < 2; id++) {
- CONTROLLER(channel,id).status.busy = 1;
- CONTROLLER(channel,id).status.drive_ready = 0;
- CONTROLLER(channel,id).reset_in_progress = 1;
-
- CONTROLLER(channel,id).status.write_fault = 0;
- CONTROLLER(channel,id).status.seek_complete = 1;
- CONTROLLER(channel,id).status.drq = 0;
- CONTROLLER(channel,id).status.corrected_data = 0;
- CONTROLLER(channel,id).status.err = 0;
-
- CONTROLLER(channel,id).error_register = 0x01; // diagnostic code: no error
-
- CONTROLLER(channel,id).current_command = 0x00;
- CONTROLLER(channel,id).buffer_index = 0;
-
- CONTROLLER(channel,id).sectors_per_block = 0x80;
- CONTROLLER(channel,id).lba_mode = 0;
-
- CONTROLLER(channel,id).control.disable_irq = 0;
- rd_lower_irq((struct vm_device *)(ramdisk_state->private_data), channels[channel].irq);
+ break;
}
- } else if (SELECTED_CONTROLLER(channel).reset_in_progress &&
- !SELECTED_CONTROLLER(channel).control.reset) {
- // Clear BSY and DRDY
- Ramdisk_Print("\t\tReset complete {%s}\n", SELECTED_TYPE_STRING(channel));
- for (id = 0; id < 2; id++) {
- CONTROLLER(channel,id).status.busy = 0;
- CONTROLLER(channel,id).status.drive_ready = 1;
- CONTROLLER(channel,id).reset_in_progress = 0;
+ case 0x42: // read sub-channel
+ {
+ //bool msf = get_packet_field(channel,1, 1, 1);
+ bool sub_q = get_packet_field(channel,2, 6, 1);
+ //uint8_t data_format = get_packet_byte(channel,3);
+ //uint8_t track_number = get_packet_byte(channel,6);
+ uint16_t alloc_length = get_packet_word(channel,7);
- // Device signature
- if (DRIVE_IS_HD(channel,id)) {
- Ramdisk_Print("\t\tdrive %d/%d is harddrive\n", channel, id);
- CONTROLLER(channel,id).head_no = 0;
- CONTROLLER(channel,id).sector_count = 1;
- CONTROLLER(channel,id).sector_no = 1;
- CONTROLLER(channel,id).cylinder_no = 0;
+
+ /*
+ UNUSED(msf);
+ UNUSED(data_format);
+ UNUSED(track_number);
+ */
+ if (!(drive->cdrom.ready)) {
+ rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+ rd_raise_interrupt(dev, channel);
} else {
- CONTROLLER(channel,id).head_no = 0;
- CONTROLLER(channel,id).sector_count = 1;
- CONTROLLER(channel,id).sector_no = 1;
- CONTROLLER(channel,id).cylinder_no = 0xeb14;
+ controller->buffer[0] = 0;
+ controller->buffer[1] = 0; // audio not supported
+ controller->buffer[2] = 0;
+ controller->buffer[3] = 0;
+
+ int ret_len = 4; // header size
+
+ if (sub_q) { // !sub_q == header only
+ PrintError("Read sub-channel with SubQ not implemented\n");
+ rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
+ ASC_INV_FIELD_IN_CMD_PACKET);
+ rd_raise_interrupt(dev, channel);
+ }
+
+ if (rd_init_send_atapi_command(dev, channel, atapi_command, ret_len, alloc_length, false) == -1) {
+ return -1;
+ }
+ rd_ready_to_send_atapi(dev, channel);
}
+ break;
+ }
+ case 0x51: // read disc info
+ {
+ // no-op to keep the Linux CD-ROM driver happy
+ rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
+ rd_raise_interrupt(dev, channel);
+ break;
}
+ case 0x55: // mode select
+ case 0xa6: // load/unload cd
+ case 0x4b: // pause/resume
+ case 0x45: // play audio
+ case 0x47: // play audio msf
+ case 0xbc: // play cd
+ case 0xb9: // read cd msf
+ case 0x44: // read header
+ case 0xba: // scan
+ case 0xbb: // set cd speed
+ case 0x4e: // stop play/scan
+ case 0x46: // ???
+ case 0x4a: // ???
+ PrintError("ATAPI command 0x%x not implemented yet\n",
+ atapi_command);
+ rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
+ rd_raise_interrupt(dev, channel);
+ break;
+ default:
+ PrintError("Unknown ATAPI command 0x%x (%d)\n",
+ atapi_command, atapi_command);
+ // We'd better signal the error if the user chose to continue
+ rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
+ rd_raise_interrupt(dev, channel);
+ break;
}
- Ramdisk_Print("\t\ts[0].controller.control.disable_irq = %02x\n", (channels[channel].drives[0]).controller.control.disable_irq);
- Ramdisk_Print("\t\ts[1].controller.control.disable_irq = %02x\n", (channels[channel].drives[1]).controller.control.disable_irq);
- break;
+ }
+ return 0;
+}
+
+
+
+
+int rd_init_send_atapi_command(struct vm_device * dev, struct channel_t * channel, Bit8u command, int req_length, int alloc_length, bool lazy)
+{
+ struct drive_t * drive = &(channel->drives[channel->drive_select]);
+ struct controller_t * controller = &(drive->controller);
+
+ // controller->byte_count is a union of controller->cylinder_no;
+ // lazy is used to force a data read in the buffer at the next read.
+
+ PrintDebug("[rd_init_send_atapi_cmd]\n");
+
+ if (controller->byte_count == 0xffff) {
+ controller->byte_count = 0xfffe;
+ }
+
+ if ((controller->byte_count & 1) &&
+ !(alloc_length <= controller->byte_count)) {
+
+ PrintDebug("\t\tOdd byte count (0x%04x) to ATAPI command 0x%02x, using 0x%x\n",
+ controller->byte_count,
+ command,
+ controller->byte_count - 1);
- default:
- RD_PANIC("\t\thard drive: io write to address %x = %02x\n",
- (unsigned) address, (unsigned) value);
+ controller->byte_count -= 1;
+ }
+
+ if (controller->byte_count == 0) {
+ PrintError("\t\tATAPI command with zero byte count\n");
+ return -1;
+ }
+
+ if (alloc_length < 0) {
+ PrintError("\t\tAllocation length < 0\n");
+ return -1;
+ }
+
+ if (alloc_length == 0) {
+ alloc_length = controller->byte_count;
+ }
+
+ controller->interrupt_reason.i_o = 1;
+ controller->interrupt_reason.c_d = 0;
+ controller->status.busy = 0;
+ controller->status.drq = 1;
+ controller->status.err = 0;
+
+ // no bytes transfered yet
+ if (lazy) {
+ controller->buffer_index = 2048;
+ } else {
+ controller->buffer_index = 0;
+ }
+
+ controller->drq_index = 0;
+
+ if (controller->byte_count > req_length) {
+ controller->byte_count = req_length;
+ }
+
+ if (controller->byte_count > alloc_length) {
+ controller->byte_count = alloc_length;
}
+
+ drive->atapi.command = command;
+ drive->atapi.drq_bytes = controller->byte_count;
+ drive->atapi.total_bytes_remaining = (req_length < alloc_length) ? req_length : alloc_length;
- return;
+ // if (lazy) {
+ // // bias drq_bytes and total_bytes_remaining
+ // SELECTED_DRIVE(channel).atapi.drq_bytes += 2048;
+ // SELECTED_DRIVE(channel).atapi.total_bytes_remaining += 2048;
+ // }
+
+ return 0;
}
-static
-void rd_identify_ATAPI_drive(struct channel_t *channels, Bit8u channel)
+
+ void rd_ready_to_send_atapi(struct vm_device * dev, struct channel_t * channel) {
+ PrintDebug("[rd_ready_to_send_atapi]\n");
+
+ rd_raise_interrupt(dev, channel);
+}
+
+
+
+
+
+void rd_atapi_cmd_error(struct vm_device * dev, struct channel_t * channel, sense_t sense_key, asc_t asc)
+{
+ struct drive_t * drive = &(channel->drives[channel->drive_select]);
+ struct controller_t * controller = &(drive->controller);
+
+#ifdef DEBUG_RAMDISK
+ {
+ struct ramdisk_t *ramdisk = (struct ramdisk_t *)(dev->private_data);
+ PrintDebug("[rd_atapi_cmd_error]\n");
+ PrintDebug("Error: atapi_cmd_error channel=%02x key=%02x asc=%02x\n",
+ get_channel_no(ramdisk, channel), sense_key, asc);
+ }
+#endif
+
+ controller->error_register = sense_key << 4;
+ controller->interrupt_reason.i_o = 1;
+ controller->interrupt_reason.c_d = 1;
+ controller->interrupt_reason.rel = 0;
+ controller->status.busy = 0;
+ controller->status.drive_ready = 1;
+ controller->status.write_fault = 0;
+ controller->status.drq = 0;
+ controller->status.err = 1;
+
+ drive->sense.sense_key = sense_key;
+ drive->sense.asc = asc;
+ drive->sense.ascq = 0;
+}
+
+
+
+void rd_atapi_cmd_nop(struct vm_device * dev, struct channel_t * channel)
{
- unsigned i;
+ struct drive_t * drive = &(channel->drives[channel->drive_select]);
+ struct controller_t * controller = &(drive->controller);
+
+ PrintDebug("[rd_atapi_cmd_nop]\n");
+ controller->interrupt_reason.i_o = 1;
+ controller->interrupt_reason.c_d = 1;
+ controller->interrupt_reason.rel = 0;
+ controller->status.busy = 0;
+ controller->status.drive_ready = 1;
+ controller->status.drq = 0;
+ controller->status.err = 0;
+}
+
+
+
+
+void rd_identify_ATAPI_drive(struct vm_device * dev, struct channel_t * channel)
+{
+ struct drive_t * drive = &(channel->drives[channel->drive_select]);
+ struct controller_t * controller = &(drive->controller);
+
+
+ uint_t i;
const char* serial_number = " VT00001\0\0\0\0\0\0\0\0\0\0\0\0";
const char* firmware = "ALPHA1 ";
- SELECTED_DRIVE(channel).id_drive[0] = (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0); // Removable CDROM, 50us response, 12 byte packets
-
- for (i = 1; i <= 9; i++)
- SELECTED_DRIVE(channel).id_drive[i] = 0;
+ drive->id_drive[0] = (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0); // Removable CDROM, 50us response, 12 byte packets
+ for (i = 1; i <= 9; i++) {
+ drive->id_drive[i] = 0;
+ }
for (i = 0; i < 10; i++) {
- SELECTED_DRIVE(channel).id_drive[10+i] = (serial_number[i*2] << 8) |
- serial_number[i*2 + 1];
+ drive->id_drive[10 + i] = ((serial_number[i * 2] << 8) |
+ (serial_number[(i * 2) + 1]));
}
- for (i = 20; i <= 22; i++)
- SELECTED_DRIVE(channel).id_drive[i] = 0;
-
+ for (i = 20; i <= 22; i++) {
+ drive->id_drive[i] = 0;
+ }
for (i = 0; i < strlen(firmware)/2; i++) {
- SELECTED_DRIVE(channel).id_drive[23+i] = (firmware[i*2] << 8) |
- firmware[i*2 + 1];
+ drive->id_drive[23 + i] = ((firmware[i * 2] << 8) |
+ (firmware[(i * 2) + 1]));
}
- V3_ASSERT((23+i) == 27);
+ V3_ASSERT((23 + i) == 27);
- for (i = 0; i < strlen((char *) SELECTED_MODEL(channel))/2; i++) {
- SELECTED_DRIVE(channel).id_drive[27+i] = (SELECTED_MODEL(channel)[i*2] << 8) |
- SELECTED_MODEL(channel)[i*2 + 1];
+ for (i = 0; i < strlen((char *)(drive->model_no)) / 2; i++) {
+ drive->id_drive[27 + i] = ((drive->model_no[i * 2] << 8) |
+ (drive->model_no[(i * 2) + 1]));
}
- V3_ASSERT((27+i) == 47);
+ V3_ASSERT((27 + i) == 47);
- SELECTED_DRIVE(channel).id_drive[47] = 0;
- SELECTED_DRIVE(channel).id_drive[48] = 1; // 32 bits access
+ drive->id_drive[47] = 0;
+ drive->id_drive[48] = 1; // 32 bits access
- SELECTED_DRIVE(channel).id_drive[49] = (1 << 9); // LBA supported
+ drive->id_drive[49] = (1 << 9); // LBA supported
- SELECTED_DRIVE(channel).id_drive[50] = 0;
- SELECTED_DRIVE(channel).id_drive[51] = 0;
- SELECTED_DRIVE(channel).id_drive[52] = 0;
+ drive->id_drive[50] = 0;
+ drive->id_drive[51] = 0;
+ drive->id_drive[52] = 0;
- SELECTED_DRIVE(channel).id_drive[53] = 3; // words 64-70, 54-58 valid
+ drive->id_drive[53] = 3; // words 64-70, 54-58 valid
- for (i = 54; i <= 62; i++)
- SELECTED_DRIVE(channel).id_drive[i] = 0;
+ for (i = 54; i <= 62; i++) {
+ drive->id_drive[i] = 0;
+ }
// copied from CFA540A
- SELECTED_DRIVE(channel).id_drive[63] = 0x0103; // variable (DMA stuff)
- SELECTED_DRIVE(channel).id_drive[64] = 0x0001; // PIO
- SELECTED_DRIVE(channel).id_drive[65] = 0x00b4;
- SELECTED_DRIVE(channel).id_drive[66] = 0x00b4;
- SELECTED_DRIVE(channel).id_drive[67] = 0x012c;
- SELECTED_DRIVE(channel).id_drive[68] = 0x00b4;
-
- SELECTED_DRIVE(channel).id_drive[69] = 0;
- SELECTED_DRIVE(channel).id_drive[70] = 0;
- SELECTED_DRIVE(channel).id_drive[71] = 30; // faked
- SELECTED_DRIVE(channel).id_drive[72] = 30; // faked
- SELECTED_DRIVE(channel).id_drive[73] = 0;
- SELECTED_DRIVE(channel).id_drive[74] = 0;
-
- SELECTED_DRIVE(channel).id_drive[75] = 0;
-
- for (i = 76; i <= 79; i++)
- SELECTED_DRIVE(channel).id_drive[i] = 0;
-
- SELECTED_DRIVE(channel).id_drive[80] = 0x1e; // supports up to ATA/ATAPI-4
- SELECTED_DRIVE(channel).id_drive[81] = 0;
- SELECTED_DRIVE(channel).id_drive[82] = 0;
- SELECTED_DRIVE(channel).id_drive[83] = 0;
- SELECTED_DRIVE(channel).id_drive[84] = 0;
- SELECTED_DRIVE(channel).id_drive[85] = 0;
- SELECTED_DRIVE(channel).id_drive[86] = 0;
- SELECTED_DRIVE(channel).id_drive[87] = 0;
- SELECTED_DRIVE(channel).id_drive[88] = 0;
-
- for (i = 89; i <= 126; i++)
- SELECTED_DRIVE(channel).id_drive[i] = 0;
-
- SELECTED_DRIVE(channel).id_drive[127] = 0;
- SELECTED_DRIVE(channel).id_drive[128] = 0;
-
- for (i = 129; i <= 159; i++)
- SELECTED_DRIVE(channel).id_drive[i] = 0;
-
- for (i = 160; i <= 255; i++)
- SELECTED_DRIVE(channel).id_drive[i] = 0;
+ drive->id_drive[63] = 0x0103; // variable (DMA stuff)
+ drive->id_drive[64] = 0x0001; // PIO
+ drive->id_drive[65] = 0x00b4;
+ drive->id_drive[66] = 0x00b4;
+ drive->id_drive[67] = 0x012c;
+ drive->id_drive[68] = 0x00b4;
+
+ drive->id_drive[69] = 0;
+ drive->id_drive[70] = 0;
+ drive->id_drive[71] = 30; // faked
+ drive->id_drive[72] = 30; // faked
+ drive->id_drive[73] = 0;
+ drive->id_drive[74] = 0;
+
+ drive->id_drive[75] = 0;
+
+ for (i = 76; i <= 79; i++) {
+ drive->id_drive[i] = 0;
+ }
+
+ drive->id_drive[80] = 0x1e; // supports up to ATA/ATAPI-4
+ drive->id_drive[81] = 0;
+ drive->id_drive[82] = 0;
+ drive->id_drive[83] = 0;
+ drive->id_drive[84] = 0;
+ drive->id_drive[85] = 0;
+ drive->id_drive[86] = 0;
+ drive->id_drive[87] = 0;
+ drive->id_drive[88] = 0;
+
+ for (i = 89; i <= 126; i++) {
+ drive->id_drive[i] = 0;
+ }
+
+ drive->id_drive[127] = 0;
+ drive->id_drive[128] = 0;
+
+ for (i = 129; i <= 159; i++) {
+ drive->id_drive[i] = 0;
+ }
+
+ for (i = 160; i <= 255; i++) {
+ drive->id_drive[i] = 0;
+ }
// now convert the id_drive array (native 256 word format) to
// the controller buffer (512 bytes)
Bit16u temp16;
for (i = 0; i <= 255; i++) {
- temp16 = SELECTED_DRIVE(channel).id_drive[i];
- SELECTED_CONTROLLER(channel).buffer[i*2] = temp16 & 0x00ff;
- SELECTED_CONTROLLER(channel).buffer[i*2+1] = temp16 >> 8;
+ temp16 = drive->id_drive[i];
+ controller->buffer[i * 2] = temp16 & 0x00ff;
+ controller->buffer[i * 2 + 1] = temp16 >> 8;
}
return;
+
+
+
+
static
-void rd_raise_interrupt(struct channel_t *channels, Bit8u channel)
+void rd_init_mode_sense_single(struct vm_device * dev,
+ struct channel_t * channel, const void* src, int size)
{
- Bit32u irq;
- struct vm_device *dev;
+ struct drive_t * drive = &(channel->drives[channel->drive_select]);
+ struct controller_t * controller = &(drive->controller);
- Ramdisk_Print("[raise_interrupt] disable_irq = %02x\n", SELECTED_CONTROLLER(channel).control.disable_irq);
+ PrintDebug("[rd_init_mode_sense_single]\n");
- if (!SELECTED_CONTROLLER(channel).control.disable_irq) {
- Ramdisk_Print("\t\traising interrupt\n");
- } else {
- Ramdisk_Print("\t\tNot raising interrupt\n");
- }
- if (!SELECTED_CONTROLLER(channel).control.disable_irq) {
- irq = channels[channel].irq;
- Ramdisk_Print("\t\tRaising interrupt %d {%s}\n\n", irq, SELECTED_TYPE_STRING(channel));
- // DEV_pic_raise_irq(irq);
- dev = (struct vm_device*) ramdisk_state->private_data;
- Ramdisk_Print("\t\tdev = %x\n", dev);
- dev->vm->vm_ops.raise_irq(dev->vm, irq);
- } else {
- Ramdisk_Print("\t\tirq is disabled\n");
- }
+ // Header
+ controller->buffer[0] = (size + 6) >> 8;
+ controller->buffer[1] = (size + 6) & 0xff;
+ controller->buffer[2] = 0x70; // no media present
+ controller->buffer[3] = 0; // reserved
+ controller->buffer[4] = 0; // reserved
+ controller->buffer[5] = 0; // reserved
+ controller->buffer[6] = 0; // reserved
+ controller->buffer[7] = 0; // reserved
- return;
+ // Data
+ memcpy(controller->buffer + 8, src, size);
}
-static
-void rd_lower_irq(struct vm_device *dev, Bit32u irq)// __attribute__(regparm(1))
-{
- Ramdisk_Print("[lower_irq] irq = %d\n", irq);
- dev->vm->vm_ops.lower_irq(dev->vm, irq);
+
+
+static void rd_command_aborted(struct vm_device * dev,
+ struct channel_t * channel, unsigned value) {
+ struct drive_t * drive = &(channel->drives[channel->drive_select]);
+ struct controller_t * controller = &(drive->controller);
+
+ PrintDebug("[rd_command_aborted]\n");
+ PrintDebug("\t\taborting on command 0x%02x {%s}\n", value, device_type_to_str(drive->device_type));
+
+ controller->current_command = 0;
+ controller->status.busy = 0;
+ controller->status.drive_ready = 1;
+ controller->status.err = 1;
+ controller->error_register = 0x04; // command ABORTED
+ controller->status.drq = 0;
+ controller->status.seek_complete = 0;
+ controller->status.corrected_data = 0;
+ controller->buffer_index = 0;
+
+ rd_raise_interrupt(dev, channel);
}
-/*
- * Public Routines
- */
-static
-uint_t ramdisk_read_port(ushort_t port,
- void *src,
- uint_t length,
- struct vm_device *dev)
-{
- uint_t i;
- Ramdisk_Print("[ramdisk_read_port] port = %x, length = %d\n", port, length);
- switch (length) {
- case 1:
- ((uchar_t*)src)[0] = rd_read_handler(ramdisk_state->channels, port, length);
- break;
- case 2:
- ((ushort_t*)src)[0] = rd_read_handler(ramdisk_state->channels, port, length);
- break;
- case 4:
- ((uint_t*)src)[0] = rd_read_handler(ramdisk_state->channels, port, length);
- break;
- default:
- for (i = 0; i < length; i++) {
- ((uchar_t*)src)[i] = rd_read_handler(ramdisk_state->channels, port, 1);
- }
- }//switch length
+static int ramdisk_init_device(struct vm_device *dev) {
+ struct ramdisk_t *ramdisk= (struct ramdisk_t *)dev->private_data;
+
+ PrintDebug("Initializing Ramdisk\n");
+
+
+ rd_init_hardware(ramdisk);
+
+
+ dev_hook_io(dev, PRI_CTRL_PORT,
+ &read_status_port, &write_ctrl_port);
+
+ dev_hook_io(dev, PRI_DATA_PORT,
+ &read_data_port, &write_data_port);
+ dev_hook_io(dev, PRI_FEATURES_PORT,
+ &read_general_port, &write_general_port);
+ dev_hook_io(dev, PRI_SECT_CNT_PORT,
+ &read_general_port, &write_general_port);
+ dev_hook_io(dev, PRI_SECT_ADDR1_PORT,
+ &read_general_port, &write_general_port);
+ dev_hook_io(dev, PRI_SECT_ADDR2_PORT,
+ &read_general_port, &write_general_port);
+ dev_hook_io(dev, PRI_SECT_ADDR3_PORT,
+ &read_general_port, &write_general_port);
+ dev_hook_io(dev, PRI_DRV_SEL_PORT,
+ &read_general_port, &write_general_port);
+ dev_hook_io(dev, PRI_CMD_PORT,
+ &read_status_port, &write_cmd_port);
+
+
+ dev_hook_io(dev, SEC_CTRL_PORT,
+ &read_status_port, &write_ctrl_port);
+
+ dev_hook_io(dev, SEC_DATA_PORT,
+ &read_data_port, &write_data_port);
+ dev_hook_io(dev, SEC_FEATURES_PORT,
+ &read_general_port, &write_general_port);
+ dev_hook_io(dev, SEC_SECT_CNT_PORT,
+ &read_general_port, &write_general_port);
+ dev_hook_io(dev, SEC_SECT_ADDR1_PORT,
+ &read_general_port, &write_general_port);
+ dev_hook_io(dev, SEC_SECT_ADDR2_PORT,
+ &read_general_port, &write_general_port);
+ dev_hook_io(dev, SEC_SECT_ADDR3_PORT,
+ &read_general_port, &write_general_port);
+ dev_hook_io(dev, SEC_DRV_SEL_PORT,
+ &read_general_port, &write_general_port);
+ dev_hook_io(dev, SEC_CMD_PORT,
+ &read_status_port, &write_cmd_port);
+
+
+
+ dev_hook_io(dev, SEC_ADDR_REG_PORT,
+ &read_general_port, &write_general_port);
+
+ dev_hook_io(dev, PRI_ADDR_REG_PORT,
+ &read_general_port, &write_general_port);
+
+
+
+ return 0;
- return length;
}
-static
-uint_t ramdisk_write_port(ushort_t port,
- void *src,
- uint_t length,
- struct vm_device *dev)
+static int ramdisk_deinit_device(struct vm_device *dev) {
+ struct ramdisk_t *ramdisk = (struct ramdisk_t *)(dev->private_data);
+ rd_close_harddrive(ramdisk);
+ return 0;
+}
+
+static struct vm_device_ops dev_ops = {
+ .init = ramdisk_init_device,
+ .deinit = ramdisk_deinit_device,
+ .reset = NULL,
+ .start = NULL,
+ .stop = NULL,
+};
+
+
+
+
+struct vm_device *create_ramdisk()
{
- Ramdisk_Print("[ramdisk_write_port] port = %x, length = %d\n", port, length);
- /*
- uint_t i;
- for (i = 0; i < length; i++)
- Ramdisk_Print("\t\tsrc[%d] = 0x%02x\n", i, ((uchar_t*)src)[i]);
- */
+ struct ramdisk_t *ramdisk;
+ ramdisk = (struct ramdisk_t *)V3_Malloc(sizeof(struct ramdisk_t));
+ V3_ASSERT(ramdisk != NULL);
- switch(length) {
- case 1:
- rd_write_handler(ramdisk_state->channels, port, *((uchar_t *)src), length);
- break;
- case 2:
- rd_write_handler(ramdisk_state->channels, port, *((ushort_t *)src), length);
- break;
- case 4:
- rd_write_handler(ramdisk_state->channels, port, *((uint_t *)src), length);
- break;
- default:
- rd_write_handler(ramdisk_state->channels, port, *((uchar_t *)src), length);
- break;
+ PrintDebug("[create_ramdisk]\n");
+
+ struct vm_device *device = create_device("RAMDISK", &dev_ops, ramdisk);
+
+ return device;
+}
+
+
+
+
+#ifdef DEBUG_RAMDISK
+
+static void rd_print_state(struct ramdisk_t * ramdisk) {
+ uchar_t channel;
+ uchar_t device;
+ struct channel_t * channels = (struct channel_t *)(&(ramdisk->channels));
+
+ /*
+ for (channel = 0; channel < MAX_ATA_CHANNEL; channel++) {
+ memset((char *)(channels + channel), 0, sizeof(struct channel_t));
}
+ */
+ PrintDebug("sizeof(*channels) = %d\n", sizeof(*channels));
+ PrintDebug("sizeof(channles->drives[0].controller) = %d\n", sizeof((channels->drives[0].controller)));
+ PrintDebug("sizeof(channles->drives[0].cdrom) = %d\n", sizeof((channels->drives[0].cdrom)));
+ PrintDebug("sizeof(channles->drives[0].sense) = %d\n", sizeof((channels->drives[0].sense)));
+ PrintDebug("sizeof(channles->drives[0].atapi) = %d\n", sizeof((channels->drives[0].atapi)));
+
- return 1;
+ PrintDebug("sizeof(channles->drives[0].controller.status) = %d\n",
+ sizeof((channels->drives[0].controller.status)));
+ PrintDebug("sizeof(channles->drives[0].controller.sector_count) = %d\n",
+ sizeof((channels->drives[0].controller.sector_count)));
+ PrintDebug("sizeof(channles->drives[0].controller.interrupt_reason) = %d\n",
+ sizeof((channels->drives[0].controller.interrupt_reason)));
+
+ PrintDebug("sizeof(channles->drives[0].controller.cylinder_no) = %d\n",
+ sizeof((channels->drives[0].controller.cylinder_no)));
+ PrintDebug("sizeof(channles->drives[0].controller.byte_count) = %d\n",
+ sizeof((channels->drives[0].controller.byte_count)));
+
+
+ PrintDebug("sizeof(channles->drives[0].controller.control) = %d\n",
+ sizeof((channels->drives[0].controller.control)));
+
+
+ for (channel = 0; channel < MAX_ATA_CHANNEL; channel++){
+
+ for (device = 0; device < 2; device++){
+
+ // Initialize controller state, even if device is not present
+ PrintDebug("channels[%d].drives[%d].controller.status.busy = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.status.busy);
+ PrintDebug("channels[%d].drives[%d].controller.status.drive_ready = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.status.drive_ready);
+ PrintDebug("channels[%d].drives[%d].controller.status.write_fault = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.status.write_fault);
+ PrintDebug("channels[%d].drives[%d].controller.status.seek_complete = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.status.seek_complete);
+ PrintDebug("channels[%d].drives[%d].controller.status.drq = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.status.drq);
+ PrintDebug("channels[%d].drives[%d].controller.status.corrected_data = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.status.corrected_data);
+ PrintDebug("channels[%d].drives[%d].controller.status.index_pulse = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.status.index_pulse);
+ PrintDebug("channels[%d].drives[%d].controller.status.index_pulse_count = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.status.index_pulse_count);
+ PrintDebug("channels[%d].drives[%d].controller.status.err = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.status.err);
+
+
+ PrintDebug("channels[%d].drives[%d].controller.error_register = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.error_register);
+ PrintDebug("channels[%d].drives[%d].controller.head_no = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.head_no);
+ PrintDebug("channels[%d].drives[%d].controller.sector_count = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.sector_count);
+ PrintDebug("channels[%d].drives[%d].controller.sector_no = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.sector_no);
+ PrintDebug("channels[%d].drives[%d].controller.cylinder_no = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.cylinder_no);
+ PrintDebug("channels[%d].drives[%d].controller.current_command = %02x\n",
+ channel, device,
+ channels[channel].drives[device].controller.current_command);
+ PrintDebug("channels[%d].drives[%d].controller.buffer_index = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.buffer_index);
+
+
+ PrintDebug("channels[%d].drives[%d].controller.control.reset = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.control.reset);
+ PrintDebug("channels[%d].drives[%d].controller.control.disable_irq = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.control.disable_irq);
+
+
+ PrintDebug("channels[%d].drives[%d].controller.reset_in_progress = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.reset_in_progress);
+ PrintDebug("channels[%d].drives[%d].controller.sectors_per_block = %02x\n",
+ channel, device,
+ channels[channel].drives[device].controller.sectors_per_block);
+ PrintDebug("channels[%d].drives[%d].controller.lba_mode = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.lba_mode);
+ PrintDebug("channels[%d].drives[%d].controller.features = %d\n",
+ channel, device,
+ channels[channel].drives[device].controller.features);
+
+
+ PrintDebug("channels[%d].drives[%d].model_no = %s\n",
+ channel, device,
+ channels[channel].drives[device].model_no);
+ PrintDebug("channels[%d].drives[%d].device_type = %d\n",
+ channel, device,
+ channels[channel].drives[device].device_type);
+ PrintDebug("channels[%d].drives[%d].cdrom.locked = %d\n",
+ channel, device,
+ channels[channel].drives[device].cdrom.locked);
+ PrintDebug("channels[%d].drives[%d].sense.sense_key = %d\n",
+ channel, device,
+ channels[channel].drives[device].sense.sense_key);
+ PrintDebug("channels[%d].drives[%d].sense.asc = %d\n",
+ channel, device,
+ channels[channel].drives[device].sense.asc);
+ PrintDebug("channels[%d].drives[%d].sense.ascq = %d\n",
+ channel, device,
+ channels[channel].drives[device].sense.ascq);
+
+
+
+ PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.c_d = %02x\n",
+ channel, device,
+ channels[channel].drives[device].controller.interrupt_reason.c_d);
+
+ PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.i_o = %02x\n",
+ channel, device,
+ channels[channel].drives[device].controller.interrupt_reason.i_o);
+
+ PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.rel = %02x\n",
+ channel, device,
+ channels[channel].drives[device].controller.interrupt_reason.rel);
+
+ PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.tag = %02x\n",
+ channel, device,
+ channels[channel].drives[device].controller.interrupt_reason.tag);
+
+ PrintDebug("channels[%d].drives[%d].cdrom.ready = %d\n",
+ channel, device,
+ channels[channel].drives[device].cdrom.ready);
+
+ } //for device
+ } //for channel
+
+ return;
}
+#if 0
+static void trace_info(ushort_t port, void *src, uint_t length) {
-static void trace_info(ushort_t port, void *src, uint_t length)
-{
switch(port){
case 0x3e8:
if (length == 1 && *((uchar_t*) src) == ATA_DETECT)
- Ramdisk_Print("ata_dectect()\n");
+ PrintDebug("ata_detect()\n");
break;
case 0x3e9:
if (length == 1 && *((uchar_t*) src) == ATA_RESET)
- Ramdisk_Print("ata_reset()\n");
+ PrintDebug("ata_reset()\n");
break;
case 0x3ea:
if (length == 1 && *((uchar_t*) src) == ATA_CMD_DATA_IN)
- Ramdisk_Print("ata_cmd_data_in()\n");
+ PrintDebug("ata_cmd_data_in()\n");
break;
case 0x3eb:
if (length == 1 && *((uchar_t*) src) == ATA_CMD_DATA_OUT)
- Ramdisk_Print("ata_cmd_data_out()\n");
+ PrintDebug("ata_cmd_data_out()\n");
break;
case 0x3ec:
if (length == 1 && *((uchar_t*) src) == ATA_CMD_PACKET)
- Ramdisk_Print("ata_cmd_packet()\n");
+ PrintDebug("ata_cmd_packet()\n");
break;
case 0x3ed:
if (length == 1 && *((uchar_t*) src) == ATAPI_GET_SENSE)
- Ramdisk_Print("atapi_get_sense()\n");
+ PrintDebug("atapi_get_sense()\n");
break;
case 0x3ee:
if (length == 1 && *((uchar_t*) src) == ATAPI_IS_READY)
- Ramdisk_Print("atapi_is_ready()\n");
+ PrintDebug("atapi_is_ready()\n");
break;
case 0x3ef:
if (length == 1 && *((uchar_t*) src) == ATAPI_IS_CDROM)
- Ramdisk_Print("atapi_is_cdrom()\n");
+ PrintDebug("atapi_is_cdrom()\n");
break;
case 0x2e8:
if (length == 1 && *((uchar_t*) src) == CDEMU_INIT)
- Ramdisk_Print("cdemu_init()\n");
+ PrintDebug("cdemu_init()\n");
break;
case 0x2e9:
if (length == 1 && *((uchar_t*) src) == CDEMU_ISACTIVE)
- Ramdisk_Print("cdemu_isactive()\n");
+ PrintDebug("cdemu_isactive()\n");
break;
case 0x2ea:
if (length == 1 && *((uchar_t*) src) == CDEMU_EMULATED_DRIVE)
- Ramdisk_Print("cdemu_emulated_drive()\n");
+ PrintDebug("cdemu_emulated_drive()\n");
break;
case 0x2eb:
if (length == 1 && *((uchar_t*) src) == CDROM_BOOT)
- Ramdisk_Print("cdrom_boot()\n");
+ PrintDebug("cdrom_boot()\n");
break;
case 0x2ec:
if (length == 1 && *((uchar_t*) src) == HARD_DRIVE_POST)
- Ramdisk_Print("ata_hard_drive_post()\n");
+ PrintDebug("ata_hard_drive_post()\n");
break;
case 0x2ed:
if (length == 1)
- Ramdisk_Print("ata_device_no(%d)\n", *((uchar_t*) src));
+ PrintDebug("ata_device_no(%d)\n", *((uchar_t*) src));
break;
case 0x2ee:
if (length == 1)
- Ramdisk_Print("ata_device_type(%d)\n", *((uchar_t*) src));
+ PrintDebug("ata_device_type(%d)\n", *((uchar_t*) src));
break;
case 0x2ef:
if (length == 1 && *((uchar_t*) src) == INT13_HARDDISK)
- Ramdisk_Print("int13_harddrive()\n");
+ PrintDebug("int13_harddrive()\n");
break;
case 0x2f8:
if (length == 1 && *((uchar_t*) src) == INT13_CDROM)
- Ramdisk_Print("int13_cdrom()\n");
+ PrintDebug("int13_cdrom()\n");
break;
case 0x2f9:
if (length == 1 && *((uchar_t*) src) == INT13_CDEMU)
- Ramdisk_Print("int13_cdemu()\n");
+ PrintDebug("int13_cdemu()\n");
break;
case 0x2fa:
if (length == 1 && *((uchar_t*) src) == INT13_ELTORITO)
- Ramdisk_Print("int13_eltorito()\n");
+ PrintDebug("int13_eltorito()\n");
break;
case 0x2fb:
if (length == 1 && *((uchar_t*) src) == INT13_DISKETTE_FUNCTION)
- Ramdisk_Print("int13_diskette_function()\n");
+ PrintDebug("int13_diskette_function()\n");
break;
}
}
+#endif
-uint_t ramdisk_read_port_ignore(ushort_t port,
- void *src,
- uint_t length,
- struct vm_device *dev)
-{
- // Ramdisk_Print("[ramdisk_read_port_ignore] port = %x, length = %d\n", port, length);
- return 1;
-}
-
-uint_t ramdisk_write_port_ignore(ushort_t port,
- void *src,
- uint_t length,
- struct vm_device *dev)
-{
-
- // Ramdisk_Print("[ramdisk_write_port_ignore] port = %x, length = %d\n", port, length);
-
- trace_info(port, src, length);
- return 1;
-}
-
-//////////////////////////////////////////////////////////////////////////
-
-/*
- * ATAPI subroutines
- */
-
-static
-void rd_init_send_atapi_command(struct channel_t *channels, Bit8u channel, Bit8u command, int req_length, int alloc_length, bool lazy)
-{
- // SELECTED_CONTROLLER(channel).byte_count is a union of SELECTED_CONTROLLER(channel).cylinder_no;
- // lazy is used to force a data read in the buffer at the next read.
-
- Ramdisk_Print("[rd_init_send_atapi_cmd]\n");
- if (SELECTED_CONTROLLER(channel).byte_count == 0xffff)
- SELECTED_CONTROLLER(channel).byte_count = 0xfffe;
-
- if ((SELECTED_CONTROLLER(channel).byte_count & 1)
- && !(alloc_length <= SELECTED_CONTROLLER(channel).byte_count)) {
- Ramdisk_Print("\t\tOdd byte count (0x%04x) to ATAPI command 0x%02x, using 0x%x\n",
- SELECTED_CONTROLLER(channel).byte_count, command, SELECTED_CONTROLLER(channel).byte_count - 1);
- SELECTED_CONTROLLER(channel).byte_count -= 1;
+static int check_bit_fields(struct controller_t * controller) {
+ //Check bit fields
+ controller->sector_count = 0;
+ controller->interrupt_reason.c_d = 1;
+ if (controller->sector_count != 0x01) {
+ return INTR_REASON_BIT_ERR;
}
- if (SELECTED_CONTROLLER(channel).byte_count == 0)
- RD_PANIC("\t\tATAPI command with zero byte count\n");
-
- if (alloc_length < 0)
- RD_PANIC("\t\tAllocation length < 0\n");
- if (alloc_length == 0)
- alloc_length = SELECTED_CONTROLLER(channel).byte_count;
-
- SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
- SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 0;
- SELECTED_CONTROLLER(channel).status.busy = 0;
- SELECTED_CONTROLLER(channel).status.drq = 1;
- SELECTED_CONTROLLER(channel).status.err = 0;
-
- // no bytes transfered yet
- if (lazy)
- SELECTED_CONTROLLER(channel).buffer_index = 2048;
- else
- SELECTED_CONTROLLER(channel).buffer_index = 0;
- SELECTED_CONTROLLER(channel).drq_index = 0;
-
- if (SELECTED_CONTROLLER(channel).byte_count > req_length)
- SELECTED_CONTROLLER(channel).byte_count = req_length;
-
- if (SELECTED_CONTROLLER(channel).byte_count > alloc_length)
- SELECTED_CONTROLLER(channel).byte_count = alloc_length;
-
- SELECTED_DRIVE(channel).atapi.command = command;
- SELECTED_DRIVE(channel).atapi.drq_bytes = SELECTED_CONTROLLER(channel).byte_count;
- SELECTED_DRIVE(channel).atapi.total_bytes_remaining = (req_length < alloc_length) ? req_length : alloc_length;
-
- // if (lazy) {
- // // bias drq_bytes and total_bytes_remaining
- // SELECTED_DRIVE(channel).atapi.drq_bytes += 2048;
- // SELECTED_DRIVE(channel).atapi.total_bytes_remaining += 2048;
- // }
-}
-
-
-static
-void rd_atapi_cmd_error(struct channel_t *channels, Bit8u channel, sense_t sense_key, asc_t asc)
-{
- Ramdisk_Print("[rd_atapi_cmd_error]\n");
- Ramdisk_Print("Error: atapi_cmd_error channel=%02x key=%02x asc=%02x\n", channel, sense_key, asc);
-
- SELECTED_CONTROLLER(channel).error_register = sense_key << 4;
- SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
- SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
- SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
- SELECTED_CONTROLLER(channel).status.busy = 0;
- SELECTED_CONTROLLER(channel).status.drive_ready = 1;
- SELECTED_CONTROLLER(channel).status.write_fault = 0;
- SELECTED_CONTROLLER(channel).status.drq = 0;
- SELECTED_CONTROLLER(channel).status.err = 1;
+ controller->sector_count = 0;
+ controller->interrupt_reason.i_o = 1;
+ if (controller->sector_count != 0x02) {
+ return INTR_REASON_BIT_ERR;
+ }
- SELECTED_DRIVE(channel).sense.sense_key = sense_key;
- SELECTED_DRIVE(channel).sense.asc = asc;
- SELECTED_DRIVE(channel).sense.ascq = 0;
-}
-
-
-static
-void rd_atapi_cmd_nop(struct channel_t *channels, Bit8u channel)
-{
- Ramdisk_Print("[rd_atapi_cmd_nop]\n");
- SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
- SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
- SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
- SELECTED_CONTROLLER(channel).status.busy = 0;
- SELECTED_CONTROLLER(channel).status.drive_ready = 1;
- SELECTED_CONTROLLER(channel).status.drq = 0;
- SELECTED_CONTROLLER(channel).status.err = 0;
-}
-
-
-static
-void rd_init_mode_sense_single(struct channel_t *channels,
- Bit8u channel, const void* src, int size)
-{
- Ramdisk_Print("[rd_init_mode_sense_single]\n");
- // Header
- SELECTED_CONTROLLER(channel).buffer[0] = (size+6) >> 8;
- SELECTED_CONTROLLER(channel).buffer[1] = (size+6) & 0xff;
- SELECTED_CONTROLLER(channel).buffer[2] = 0x70; // no media present
- SELECTED_CONTROLLER(channel).buffer[3] = 0; // reserved
- SELECTED_CONTROLLER(channel).buffer[4] = 0; // reserved
- SELECTED_CONTROLLER(channel).buffer[5] = 0; // reserved
- SELECTED_CONTROLLER(channel).buffer[6] = 0; // reserved
- SELECTED_CONTROLLER(channel).buffer[7] = 0; // reserved
+ controller->sector_count = 0;
+ controller->interrupt_reason.rel = 1;
+ if (controller->sector_count != 0x04) {
+ return INTR_REASON_BIT_ERR;
+ }
- // Data
- memcpy(SELECTED_CONTROLLER(channel).buffer + 8, src, size);
-}
-
-
-static
-void rd_ready_to_send_atapi(struct channel_t *channels, Bit8u channel)
-{
- Ramdisk_Print("[rd_ready_to_send_atapi]\n");
- rd_raise_interrupt(ramdisk_state->channels, channel);
-}
-
-
-static
-void rd_command_aborted(struct channel_t *channels,
- Bit8u channel, unsigned value)
-{
- Ramdisk_Print("[rd_command_aborted]\n");
- Ramdisk_Print("\t\taborting on command 0x%02x {%s}\n", value, SELECTED_TYPE_STRING(channel));
- SELECTED_CONTROLLER(channel).current_command = 0;
- SELECTED_CONTROLLER(channel).status.busy = 0;
- SELECTED_CONTROLLER(channel).status.drive_ready = 1;
- SELECTED_CONTROLLER(channel).status.err = 1;
- SELECTED_CONTROLLER(channel).error_register = 0x04; // command ABORTED
- SELECTED_CONTROLLER(channel).status.drq = 0;
- SELECTED_CONTROLLER(channel).status.seek_complete = 0;
- SELECTED_CONTROLLER(channel).status.corrected_data = 0;
- SELECTED_CONTROLLER(channel).buffer_index = 0;
- rd_raise_interrupt(ramdisk_state->channels, channel);
-}
-
-
-
-/*
- * Success: return 0;
- * Failure: return integer greater than 0
- */
-
-struct ramdisk_t * create_ramdisk()
-{
- struct ramdisk_t *ramdisk;
- ramdisk = (struct ramdisk_t *)V3_Malloc(sizeof(struct ramdisk_t));
- V3_ASSERT(ramdisk != NULL);
+ controller->sector_count = 0;
+ controller->interrupt_reason.tag = 3;
+ if (controller->sector_count != 0x18) {
+ return INTR_REASON_BIT_ERR;
+ }
- ramdisk->cops.init = &rd_init_harddrive;
- ramdisk->cops.close = &rd_close_harddrive;
- ramdisk->cops.reset = &rd_reset_harddrive;
-
- ramdisk->eops.read_port = &ramdisk_read_port;
- ramdisk->eops.write_port = &ramdisk_write_port;
- ramdisk->eops.read_port_ignore = &ramdisk_read_port_ignore;
- ramdisk->eops.write_port_ignore = &ramdisk_write_port_ignore;
-
- return ramdisk;
+ return 0;
}
+#endif
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <devices/serial.h>
#include <palacios/vmm.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <devices/simple_pic.h>
#include <palacios/vmm_intr.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <devices/timer.h>
#include <palacios/vmm.h>
+++ /dev/null
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
-#include <geekos/debug.h>
-
-
-void PrintBoth(const char * format, ...) {
- va_list args;
-
- va_start(args, format);
- PrintList(format, args);
- SerialPrintList(format, args);
- va_end(args);
-}
+++ /dev/null
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
-#include <geekos/queue.h>
-
-
-
-void init_queue(struct gen_queue * queue) {
- queue->num_entries = 0;
- INIT_LIST_HEAD(&(queue->entries));
-}
-
-
-struct gen_queue * create_queue() {
- struct gen_queue * tmp_queue = Malloc(sizeof(struct gen_queue));
- init_queue(tmp_queue);
- return tmp_queue;
-}
-
-void enqueue(struct gen_queue * queue, void * entry) {
- struct queue_entry * q_entry = Malloc(sizeof(struct queue_entry));
-
- q_entry->entry = entry;
- list_add_tail(&(q_entry->entry_list), &(queue->entries));
- queue->num_entries++;
-}
-
-
-void * dequeue(struct gen_queue * queue) {
- void * entry_val = 0;
-
- if (!list_empty(&(queue->entries))) {
- struct list_head * q_entry = queue->entries.next;
- struct queue_entry * tmp_entry = list_entry(q_entry, struct queue_entry, entry_list);
-
- entry_val = tmp_entry->entry;
- list_del(q_entry);
- Free(tmp_entry);
- }
-
- return entry_val;
-}
+++ /dev/null
-# -*- fundamental -*-
-
-.global MyBuzzVM
-MyBuzzVM:
- pushl %ebp
- movl %esp, %ebp
- pushl %esi
- pushl %ebx
- inb $97, %al
- movl $97, %ecx
- movb %al, %bl
- orl $2, %ebx
- movl %eax, %esi
-.L24:
- movb %bl, %al
- movl %ecx, %edx
- outb %al, %dx
- movl $0, %edx
-.L30:
- incl %edx
- cmpl $999999, %edx
- jle .L30
- movl %esi, %eax
- movl %ecx, %edx
- outb %al, %dx
- movl $0, %edx
-.L35:
- incl %edx
- cmpl $999999, %edx
- jle .L35
- jmp .L24
-
-
-
-
-
-
-
-
-
-
-
-
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+
+
#include <palacios/svm.h>
#include <palacios/vmm.h>
#include <palacios/vm_guest_mem.h>
#include <palacios/vmm_decoder.h>
+#include <palacios/vmm_string.h>
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+
+
#include <palacios/svm_halt.h>
#include <palacios/vmm_intr.h>
-// From GeekOS
-void Yield(void);
+
//
PrintDebug("GeekOS Yield\n");
rdtscll(yield_start);
- Yield();
+ V3_Yield();
rdtscll(yield_stop);
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#include <palacios/svm_handler.h>
#include <palacios/vmm.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008 The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
#include <palacios/svm_io.h>
; -*- fundamental -*-
+;;
+;; This file is part of the Palacios Virtual Machine Monitor developed
+;; by the V3VEE Project with funding from the United States National
+;; Science Foundation and the Department of Energy.
+;;
+;; The V3VEE Project is a joint project between Northwestern University
+;; and the University of New Mexico. You can find out more at
+;; http://www.v3vee.org
+;;
+;; Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+;; Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+;; All rights reserved.
+;;
+;; Author: Jack Lange <jarusl@cs.northwestern.edu>
+;;
+;; This is free software. You are permitted to use,
+;; redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+;;
+
-;; (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
-;; (c) 2008, The V3VEE Project <http://www.v3vee.org>
%ifndef SVM_ASM
%define SVM_ASM
SVM_ERROR equ 0xFFFFFFFF
SVM_SUCCESS equ 0x00000000
-EXPORT DisableInts
-EXPORT EnableInts
EXPORT exit_test
;CLGI equ db 0x0F,0x01,0xDD
-align 8
-DisableInts:
- cli
- ret
-
-align 8
-EnableInts:
- sti
- ret
-
align 8
CLGI:
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+
#include <palacios/svm_pause.h>
#include <palacios/vmm_intr.h>
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+
#include <palacios/svm_wbinvd.h>
#include <palacios/vmm_intr.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#include <palacios/vm_dev.h>
#include <palacios/vmm.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+
#include <palacios/vm_guest.h>
#include <palacios/vmm_ctrl_regs.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vm_guest_mem.h>
#include <palacios/vmm.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vmcb.h>
#include <palacios/vmm.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vmcs.h>
-;; (c) 2008, Peter Dinda <pdinda@northwestern.edu>
-;; (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
-;; (c) 2008, The V3VEE Project <http://www.v3vee.org>
-
-
+; -*- fundamental -*-
+;;
+;; This file is part of the Palacios Virtual Machine Monitor developed
+;; by the V3VEE Project with funding from the United States National
+;; Science Foundation and the Department of Energy.
+;;
+;; The V3VEE Project is a joint project between Northwestern University
+;; and the University of New Mexico. You can find out more at
+;; http://www.v3vee.org
+;;
+;; Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+;; Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+;; Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+;; All rights reserved.
+;;
+;; Author: Peter Dinda <pdinda@northwestern.edu>
+;; Jack Lange <jarusl@cs.northwestern.edu>
+;;
+;; This is free software. You are permitted to use,
+;; redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+;;
%ifndef VMCS_FIELDS_ASM
%define VMCS_FIELDS_ASM
-/* Automatically Generated File */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Automatically Generated File
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vmcs_gen.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vmm.h>
#include <palacios/svm.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vmm_config.h>
#include <palacios/vmm.h>
#include <devices/8254.h>
#include <devices/nvram.h>
#include <devices/generic.h>
+#include <devices/ramdisk.h>
+
+
+#define USE_GENERIC 1
+#define USE_RAMDISK 1
void * region_start;
int i;
-
+ int use_ramdisk = USE_RAMDISK;
+ int use_generic = USE_GENERIC;
+
+
v3_init_time(info);
init_shadow_map(info);
{
-
+ struct vm_device * ramdisk = 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();
//struct vm_device * serial = create_serial();
+ struct vm_device * generic = NULL;
+ //Zheng 09/29/2008
+
+
+ if (use_ramdisk) {
+ PrintDebug("Creating Ramdisk\n");
+ ramdisk = create_ramdisk();
+ }
-#define GENERIC 1
-
-#if GENERIC
- generic_port_range_type range[] = {
-#if 1
+ if (use_generic) {
+ PrintDebug("Creating Generic Device\n");
+ generic = create_generic();
+
// Make the DMA controller invisible
-
- {0x00, 0x07, GENERIC_PRINT_AND_IGNORE}, // DMA 1 channels 0,1,2,3 (address, counter)
- {0xc0, 0xc7, GENERIC_PRINT_AND_IGNORE}, // DMA 2 channels 4,5,6,7 (address, counter)
- {0x87, 0x87, GENERIC_PRINT_AND_IGNORE}, // DMA 1 channel 0 page register
- {0x83, 0x83, GENERIC_PRINT_AND_IGNORE}, // DMA 1 channel 1 page register
- {0x81, 0x81, GENERIC_PRINT_AND_IGNORE}, // DMA 1 channel 2 page register
- {0x82, 0x82, GENERIC_PRINT_AND_IGNORE}, // DMA 1 channel 3 page register
- {0x8f, 0x8f, GENERIC_PRINT_AND_IGNORE}, // DMA 2 channel 4 page register
- {0x8b, 0x8b, GENERIC_PRINT_AND_IGNORE}, // DMA 2 channel 5 page register
- {0x89, 0x89, GENERIC_PRINT_AND_IGNORE}, // DMA 2 channel 6 page register
- {0x8a, 0x8a, GENERIC_PRINT_AND_IGNORE}, // DMA 2 channel 7 page register
- {0x08, 0x0f, GENERIC_PRINT_AND_IGNORE}, // DMA 1 misc registers (csr, req, smask,mode,clearff,reset,enable,mmask)
- {0xd0, 0xde, GENERIC_PRINT_AND_IGNORE}, // DMA 2 misc registers
-#endif
+ v3_generic_add_port_range(generic, 0x00, 0x07, GENERIC_PRINT_AND_IGNORE); // DMA 1 channels 0,1,2,3 (address, counter)
+ v3_generic_add_port_range(generic, 0xc0, 0xc7, GENERIC_PRINT_AND_IGNORE); // DMA 2 channels 4,5,6,7 (address, counter)
+ v3_generic_add_port_range(generic, 0x87, 0x87, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 0 page register
+ v3_generic_add_port_range(generic, 0x83, 0x83, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 1 page register
+ v3_generic_add_port_range(generic, 0x81, 0x81, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 2 page register
+ v3_generic_add_port_range(generic, 0x82, 0x82, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 3 page register
+ v3_generic_add_port_range(generic, 0x8f, 0x8f, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 4 page register
+ v3_generic_add_port_range(generic, 0x8b, 0x8b, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 5 page register
+ v3_generic_add_port_range(generic, 0x89, 0x89, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 6 page register
+ v3_generic_add_port_range(generic, 0x8a, 0x8a, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 7 page register
+ v3_generic_add_port_range(generic, 0x08, 0x0f, GENERIC_PRINT_AND_IGNORE); // DMA 1 misc registers (csr, req, smask,mode,clearff,reset,enable,mmask)
+ v3_generic_add_port_range(generic, 0xd0, 0xde, GENERIC_PRINT_AND_IGNORE); // DMA 2 misc registers
+
+
+
-
-#if 1
// Make the Serial ports invisible
+
+ v3_generic_add_port_range(generic, 0x3f8, 0x3f8+7, GENERIC_PRINT_AND_IGNORE); // COM 1
+ v3_generic_add_port_range(generic, 0x2f8, 0x2f8+7, GENERIC_PRINT_AND_IGNORE); // COM 2
+
- {0x3f8, 0x3f8+7, GENERIC_PRINT_AND_IGNORE}, // COM 1
- {0x2f8, 0x2f8+7, GENERIC_PRINT_AND_IGNORE}, // COM 2
- {0x3e8, 0x3e8+7, GENERIC_PRINT_AND_IGNORE}, // COM 3
- {0x2e8, 0x2e8+7, GENERIC_PRINT_AND_IGNORE}, // COM 4
-#endif
+
+ v3_generic_add_port_range(generic, 0x3e8, 0x3e8+7, GENERIC_PRINT_AND_IGNORE); // COM 3
+ v3_generic_add_port_range(generic, 0x2e8, 0x2e8+7, GENERIC_PRINT_AND_IGNORE); // COM 4
-#if 1
- // Make the PCI bus invisible (at least it's configuration)
+
+
- {0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE}, // PCI Config Address
- {0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE}, // PCI Config Data
-#endif
-
-#if 1
+ // Make the PCI bus invisible (at least it's configuration)
+
+ v3_generic_add_port_range(generic, 0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE); // PCI Config Address
+ v3_generic_add_port_range(generic, 0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE); // PCI Config Data
- // Monitor the IDE controllers (very slow)
+
+
+#if 0
+ if (!use_ramdisk) {
+ // Monitor the IDE controllers (very slow)
+ v3_generic_add_port_range(generic, 0x170, 0x178, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
+ v3_generic_add_port_range(generic, 0x376, 0x377, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
+ }
+
- {0x170, 0x178, GENERIC_PRINT_AND_PASSTHROUGH}, // IDE 1
- {0x376, 0x377, GENERIC_PRINT_AND_PASSTHROUGH}, // IDE 1
- {0x1f0, 0x1f8, GENERIC_PRINT_AND_PASSTHROUGH}, // IDE 0
- {0x3f6, 0x3f7, GENERIC_PRINT_AND_PASSTHROUGH}, // IDE 0
+ v3_generic_add_port_range(generic, 0x1f0, 0x1f8, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
+ v3_generic_add_port_range(generic, 0x3f6, 0x3f7, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
#endif
-
+
#if 0
-
+
// Make the floppy controllers invisible
-
- {0x3f0, 0x3f2, GENERIC_PRINT_AND_IGNORE}, // Primary floppy controller (base,statusa/statusb,DOR)
- {0x3f4, 0x3f5, GENERIC_PRINT_AND_IGNORE}, // Primary floppy controller (mainstat/datarate,data)
- {0x3f7, 0x3f7, GENERIC_PRINT_AND_IGNORE}, // Primary floppy controller (DIR)
- {0x370, 0x372, GENERIC_PRINT_AND_IGNORE}, // Secondary floppy controller (base,statusa/statusb,DOR)
- {0x374, 0x375, GENERIC_PRINT_AND_IGNORE}, // Secondary floppy controller (mainstat/datarate,data)
- {0x377, 0x377, GENERIC_PRINT_AND_IGNORE}, // Secondary floppy controller (DIR)
+
+ v3_generic_add_port_range(generic, 0x3f0, 0x3f2, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (base,statusa/statusb,DOR)
+ v3_generic_add_port_range(generic, 0x3f4, 0x3f5, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (mainstat/datarate,data)
+ v3_generic_add_port_range(generic, 0x3f7, 0x3f7, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (DIR)
+ v3_generic_add_port_range(generic, 0x370, 0x372, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (base,statusa/statusb,DOR)
+ v3_generic_add_port_range(generic, 0x374, 0x375, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (mainstat/datarate,data)
+ v3_generic_add_port_range(generic, 0x377, 0x377, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (DIR)
#endif
// Make the parallel port invisible
- {0x378, 0x37f, GENERIC_PRINT_AND_IGNORE},
+ v3_generic_add_port_range(generic, 0x378, 0x37f, GENERIC_PRINT_AND_IGNORE);
#endif
// Monitor graphics card operations
- {0x3b0, 0x3bb, GENERIC_PRINT_AND_PASSTHROUGH},
- {0x3c0, 0x3df, GENERIC_PRINT_AND_PASSTHROUGH},
+ v3_generic_add_port_range(generic, 0x3b0, 0x3bb, GENERIC_PRINT_AND_PASSTHROUGH);
+ v3_generic_add_port_range(generic, 0x3c0, 0x3df, GENERIC_PRINT_AND_PASSTHROUGH);
#endif
#if 1
// Make the ISA PNP features invisible
- {0x274, 0x277, GENERIC_PRINT_AND_IGNORE},
- {0x279, 0x279, GENERIC_PRINT_AND_IGNORE},
- {0xa79, 0xa79, GENERIC_PRINT_AND_IGNORE},
+ v3_generic_add_port_range(generic, 0x274, 0x277, GENERIC_PRINT_AND_IGNORE);
+ v3_generic_add_port_range(generic, 0x279, 0x279, GENERIC_PRINT_AND_IGNORE);
+ v3_generic_add_port_range(generic, 0xa79, 0xa79, GENERIC_PRINT_AND_IGNORE);
#endif
#if 1
// Monitor any network card (realtek ne2000) operations
- {0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH},
+ v3_generic_add_port_range(generic, 0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH);
#endif
#if 1
// Make any Bus master ide controller invisible
- {0xc000, 0xc00f, GENERIC_PRINT_AND_IGNORE},
+ v3_generic_add_port_range(generic, 0xc000, 0xc00f, GENERIC_PRINT_AND_IGNORE);
#endif
-
-
- // {0x378, 0x400, GENERIC_PRINT_AND_IGNORE}
- {0,0,0}, // sentinal - must be last
+ }
+ // v3_generic_add_port_range(generic, 0x378, 0x400, GENERIC_PRINT_AND_IGNORE);
- };
-
- struct vm_device * generic = create_generic(range, NULL, NULL);
-
-#endif
+
+
v3_attach_device(info, nvram);
//v3_attach_device(info, timer);
v3_attach_device(info, pic);
v3_attach_device(info, keyboard);
// v3_attach_device(info, serial);
+ if (use_ramdisk) {
+ v3_attach_device(info, ramdisk);
+ }
-#if GENERIC
- // Important that this be attached last!
- v3_attach_device(info, generic);
-
-#endif
+ if (use_generic) {
+ // Important that this be attached last!
+ v3_attach_device(info, generic);
+ }
PrintDebugDevMgr(info);
}
// no longer needed since we have a keyboard device
//hook_irq(&vm_info, 1);
-#if 1
+#if 0
// give floppy controller to vm
v3_hook_irq_for_guest_injection(info, 6);
#endif
-#if 1
- //primary ide
- v3_hook_irq_for_guest_injection(info, 14);
-
- // secondary ide
- v3_hook_irq_for_guest_injection(info, 15);
-#endif
+
+ if (!use_ramdisk) {
+ //primary ide
+ v3_hook_irq_for_guest_injection(info, 14);
+ // secondary ide
+ v3_hook_irq_for_guest_injection(info, 15);
+ }
//v3_hook_io_port(info, 1234, &IO_Read, NULL, info);
return 0;
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#if 0
-
-
- if (0) {
-
- // add_shared_mem_range(&(vm_info.mem_layout), 0, 0x800000, 0x10000);
- // add_shared_mem_range(&(vm_info.mem_layout), 0, 0x1000000, 0);
-
- rip = (ulong_t)(void*)&BuzzVM;
- // rip -= 0x10000;
- // rip = (addr_t)(void*)&exit_test;
- // rip -= 0x2000;
- vm_info.rip = rip;
- rsp = (addr_t)Alloc_Page();
-
- vm_info.vm_regs.rsp = (rsp +4092 );// - 0x2000;
-
-
- } else if (0) {
- //add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x1000, 0x100000);
- // add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x100000, 0x0);
-
- /*
- shadow_region_t *ent = Malloc(sizeof(shadow_region_t));;
- init_shadow_region_physical(ent,0,0x100000,GUEST_REGION_PHYSICAL_MEMORY,
- 0x100000, HOST_REGION_PHYSICAL_MEMORY);
- add_shadow_region(&(vm_info.mem_map),ent);
- */
-
- add_shadow_region_passthrough(&vm_info, 0x0, 0x100000, 0x100000);
-
- v3_hook_io_port(&vm_info, 0x61, &IO_Read, &IO_Write, NULL);
- v3_hook_io_port(&vm_info, 0x05, &IO_Read, &IO_Write_to_Serial, NULL);
-
-
-
- /*
- vm_info.cr0 = 0;
- vm_info.cs.base=0xf000;
- vm_info.cs.limit=0xffff;
- */
- //vm_info.rip = 0xfff0;
-
- vm_info.rip = 0;
- vm_info.vm_regs.rsp = 0x0;
- } else {
-
- }
-
-#endif
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vmm_mem.h>
#include <palacios/vmm.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vmm_debug.h>
#include <palacios/vmm.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#include <palacios/vmm_decoder.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vm_dev.h>
#include <palacios/vmm_dev_mgr.h>
int dev_mgr_deinit(struct guest_info * info) {
struct vm_device * dev;
struct vmm_dev_mgr * mgr = &(info->dev_mgr);
+ struct vm_device * tmp;
- list_for_each_entry(dev, &(mgr->dev_list), dev_link) {
+ list_for_each_entry_safe(dev, tmp, &(mgr->dev_list), dev_link) {
v3_unattach_device(dev);
free_device(dev);
}
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vmm.h>
#include <palacios/vmm_emulator.h>
-/* Copyright (C) 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
-/* Modifications made by Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
+/*
+ Copyright (c) 2002, 2004, Christopher Clark
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the original author; nor the names of any contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/* Modifications made by Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#include <palacios/vmm_intr.h>
#include <palacios/vmm.h>
PrintDebug("[v3_lower_irq]\n");
- // if ((info->intr_state.controller) &&
- // (info->intr_state.controller->raise_intr)) {
+ if ((info->intr_state.controller) &&
+ (info->intr_state.controller->raise_intr)) {
info->intr_state.controller->lower_intr(info->intr_state.controller_state, irq);
- //} else {
- // PrintDebug("There is no registered Interrupt Controller... (NULL POINTER)\n");
- // return -1;
- //}
+ } else {
+ PrintDebug("There is no registered Interrupt Controller... (NULL POINTER)\n");
+ return -1;
+ }
+
return 0;
}
PrintDebug("[v3_raise_irq]\n");
- // if ((info->intr_state.controller) &&
- // (info->intr_state.controller->raise_intr)) {
+ if ((info->intr_state.controller) &&
+ (info->intr_state.controller->raise_intr)) {
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;
- //}
+ } else {
+ PrintDebug("There is no registered Interrupt Controller... (NULL POINTER)\n");
+ return -1;
+ }
+
return 0;
}
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vmm_io.h>
#include <palacios/vmm_string.h>
#endif
+static int default_write(ushort_t port, void *src, uint_t length, void * priv_data);
+static int default_read(ushort_t port, void * dst, uint_t length, void * priv_data);
+
+
void init_vmm_io_map(struct guest_info * info) {
struct vmm_io_map * io_map = &(info->io_map);
io_map->num_ports = 0;
-/* FIX ME */
-static int default_write(ushort_t port, void *src, uint_t length, void * priv_data) {
- /*
-
- if (length == 1) {
- __asm__ __volatile__ (
- "outb %b0, %w1"
- :
- : "a" (*dst), "Nd" (port)
- );
- } else if (length == 2) {
- __asm__ __volatile__ (
- "outw %b0, %w1"
- :
- : "a" (*dst), "Nd" (port)
- );
- } else if (length == 4) {
- __asm__ __volatile__ (
- "outw %b0, %w1"
- :
- : "a" (*dst), "Nd" (port)
- );
- }
- */
- return 0;
-}
-
-static int default_read(ushort_t port, void * dst, uint_t length, void * priv_data)
-{
-
- /*
- uchar_t value;
-
- __asm__ __volatile__ (
- "inb %w1, %b0"
- : "=a" (value)
- : "Nd" (port)
- );
-
- return value;
- */
- return 0;
-}
int v3_hook_io_port(struct guest_info * info, uint_t port,
int (*read)(ushort_t port, void * dst, uint_t length, void * priv_data),
PrintDebug("IO Port: %hu (Read=%x) (Write=%x)\n", iter->port, iter->read, iter->write);
}
}
+
+
+
+/*
+ * Write a byte to an I/O port.
+ */
+void v3_outb(ushort_t port, uchar_t value) {
+ __asm__ __volatile__ (
+ "outb %b0, %w1"
+ :
+ : "a" (value), "Nd" (port)
+ );
+}
+
+/*
+ * Read a byte from an I/O port.
+ */
+uchar_t v3_inb(ushort_t port) {
+ uchar_t value;
+
+ __asm__ __volatile__ (
+ "inb %w1, %b0"
+ : "=a" (value)
+ : "Nd" (port)
+ );
+
+ return value;
+}
+
+/*
+ * Write a word to an I/O port.
+ */
+void v3_outw(ushort_t port, ushort_t value) {
+ __asm__ __volatile__ (
+ "outw %w0, %w1"
+ :
+ : "a" (value), "Nd" (port)
+ );
+}
+
+/*
+ * Read a word from an I/O port.
+ */
+ushort_t v3_inw(ushort_t port) {
+ ushort_t value;
+
+ __asm__ __volatile__ (
+ "inw %w1, %w0"
+ : "=a" (value)
+ : "Nd" (port)
+ );
+
+ return value;
+}
+
+/*
+ * Write a double word to an I/O port.
+ */
+void v3_outdw(ushort_t port, uint_t value) {
+ __asm__ __volatile__ (
+ "outl %0, %1"
+ :
+ : "a" (value), "Nd" (port)
+ );
+}
+
+/*
+ * Read a double word from an I/O port.
+ */
+uint_t v3_indw(ushort_t port) {
+ uint_t value;
+
+ __asm__ __volatile__ (
+ "inl %1, %0"
+ : "=a" (value)
+ : "Nd" (port)
+ );
+
+ return value;
+}
+
+
+
+
+/* FIX ME */
+static int default_write(ushort_t port, void *src, uint_t length, void * priv_data) {
+ /*
+
+ if (length == 1) {
+ __asm__ __volatile__ (
+ "outb %b0, %w1"
+ :
+ : "a" (*dst), "Nd" (port)
+ );
+ } else if (length == 2) {
+ __asm__ __volatile__ (
+ "outw %b0, %w1"
+ :
+ : "a" (*dst), "Nd" (port)
+ );
+ } else if (length == 4) {
+ __asm__ __volatile__ (
+ "outw %b0, %w1"
+ :
+ : "a" (*dst), "Nd" (port)
+ );
+ }
+ */
+ return 0;
+}
+
+static int default_read(ushort_t port, void * dst, uint_t length, void * priv_data) {
+
+ /*
+ uchar_t value;
+
+ __asm__ __volatile__ (
+ "inb %w1, %b0"
+ : "=a" (value)
+ : "Nd" (port)
+ );
+
+ return value;
+ */
+
+ return 0;
+}
; -*- fundamental -*-
-
-;; (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
-;; (c) 2008, The V3VEE Project <http://www.v3vee.org>
-
+;;
+;; This file is part of the Palacios Virtual Machine Monitor developed
+;; by the V3VEE Project with funding from the United States National
+;; Science Foundation and the Department of Energy.
+;;
+;; The V3VEE Project is a joint project between Northwestern University
+;; and the University of New Mexico. You can find out more at
+;; http://www.v3vee.org
+;;
+;; Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+;; Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+;; All rights reserved.
+;;
+;; Author: Jack Lange <jarusl@cs.northwestern.edu>
+;;
+;; This is free software. You are permitted to use,
+;; redistribute, and modify it as specified in the file "V3VEE_LICENSE"
+;;
%ifndef VMM_ASM
%define VMM_ASM
EXPORT GetTR
+; CPUID functions
+EXPORT cpuid_ecx
+EXPORT cpuid_eax
+EXPORT cpuid_edx
+; Utility Functions
+EXPORT Set_MSR
+EXPORT Get_MSR
ret
+;
+; cpuid_edx - return the edx register from cpuid
+;
+align 8
+cpuid_edx:
+ push ebp
+ mov ebp, esp
+ push edx
+ push ecx
+ push ebx
+
+ mov eax, [ebp + 8]
+ cpuid
+ mov eax, edx
+
+ pop ebx
+ pop ecx
+ pop edx
+ pop ebp
+ ret
+
+
+;
+; cpuid_ecx - return the ecx register from cpuid
+;
+align 8
+cpuid_ecx:
+ push ebp
+ mov ebp, esp
+ push edx
+ push ecx
+ push ebx
+
+ mov eax, [ebp + 8]
+ cpuid
+ mov eax, ecx
+
+ pop ebx
+ pop ecx
+ pop edx
+ pop ebp
+ ret
+
+;
+; cpuid_eax - return the eax register from cpuid
+;
+align 8
+cpuid_eax:
+ push ebp
+ mov ebp, esp
+ push edx
+ push ecx
+ push ebx
+
+ mov eax, [esp+4]
+ cpuid
+
+ pop ebx
+ pop ecx
+ pop edx
+ pop ebp
+ ret
+
+;
+; Set_MSR - Set the value of a given MSR
+;
+align 8
+Set_MSR:
+ push ebp
+ mov ebp, esp
+ pusha
+ mov eax, [ebp+16]
+ mov edx, [ebp+12]
+ mov ecx, [ebp+8]
+ wrmsr
+ popa
+ pop ebp
+ ret
+
+
+
+;
+; Get_MSR - Get the value of a given MSR
+; void Get_MSR(int MSR, void * high_byte, void * low_byte);
+;
+align 8
+Get_MSR:
+ push ebp
+ mov ebp, esp
+ pusha
+ mov ecx, [ebp+8]
+ rdmsr
+ mov ebx, [ebp+12]
+ mov [ebx], edx
+ mov ebx, [ebp+16]
+ mov [ebx], eax
+ popa
+ pop ebp
+ ret
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vmm_mem.h>
#include <palacios/vmm.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vmm_paging.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vmm_queue.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vmm_shadow_paging.h>
/*
- * String library
- * Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
- * (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * $Revision: 1.2 $
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "COPYING".
+ * String library
+ * Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
+ * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-
+/* Modifications by Jack Lange <jarusl@cs.northwestern.edu> */
*/
+
+#define NEED_MEMSET 0
+#define NEED_MEMCPY 0
+#define NEED_MEMCMP 0
+#define NEED_STRLEN 0
+#define NEED_STRNLEN 0
+#define NEED_STRCMP 0
+#define NEED_STRNCMP 0
+#define NEED_STRCAT 0
+#define NEED_STRNCAT 0
+#define NEED_STRCPY 0
+#define NEED_STRNCPY 0
+#define NEED_STRDUP 0
+#define NEED_ATOI 0
+#define NEED_STRCHR 0
+#define NEED_STRRCHR 0
+#define NEED_STRPBRK 0
+
+
+
#include <palacios/vmm_string.h>
#include <palacios/vmm.h>
return (int)(x + e) + 1;
}
-#if 0
+
+#if NEED_MEMSET
void* memset(void* s, int c, size_t n)
{
unsigned char* p = (unsigned char*) s;
return s;
}
+#endif
-
+#if NEED_MEMCPY
void* memcpy(void *dst, const void* src, size_t n)
{
unsigned char* d = (unsigned char*) dst;
return dst;
}
+#endif
+#if NEED_CMP
int memcmp(const void *s1_, const void *s2_, size_t n)
{
const signed char *s1 = s1_, *s2 = s2_;
return 0;
}
+#endif
+
+#if NEED_STRLEN
size_t strlen(const char* s)
{
size_t len = 0;
++len;
return len;
}
+#endif
+
+
+#if NEED_STRNLEN
/*
* This it a GNU extension.
* It is like strlen(), but it will check at most maxlen
++len;
return len;
}
+#endif
+
+#if NEED_STRCMP
int strcmp(const char* s1, const char* s2)
{
while (1) {
++s2;
}
}
+#endif
+
+#if NEED_STRNCMP
int strncmp(const char* s1, const char* s2, size_t limit)
{
size_t i = 0;
/* limit reached and equal */
return 0;
}
+#endif
+
+#if NEED_STRCAT
char *strcat(char *s1, const char *s2)
{
char *t1;
return t1;
}
+#endif
+
+
+#if NEED_STRNCAT
+char *strncat(char *s1, const char *s2, size_t limit)
+{
+ size_t i = 0;
+ char *t1;
+ t1 = s1;
+ while (*s1) s1++;
+ while (i < limit) {
+ if(*s2 == '\0') break;
+ *s1++ = *s2++;
+ }
+ *s1 = '\0';
+ return t1;
+}
+#endif
+
+
+#if NEED_STRCPY
char *strcpy(char *dest, const char *src)
{
char *ret = dest;
return ret;
}
+#endif
+
+#if NEED_STRNCPY
char *strncpy(char *dest, const char *src, size_t limit)
{
char *ret = dest;
return ret;
}
+#endif
+
+
+#if NEED_STRDUP
char *strdup(const char *s1)
{
char *ret;
return ret;
}
+#endif
+
+
+
+#if NEED_ATOI
int atoi(const char *buf)
{
int ret = 0;
return ret;
}
+#endif
+
+#if NEED_STRCHR
char *strchr(const char *s, int c)
{
while (*s != '\0') {
}
return 0;
}
+#endif
+
+#if NEED_STRRCHR
char *strrchr(const char *s, int c)
{
size_t len = strlen(s);
}
return 0;
}
+#endif
+#if NEED_STRPBRK
char *strpbrk(const char *s, const char *accept)
{
size_t setLen = strlen(accept);
return 0;
}
-
#endif
+
-; Symbol mangling macros
-; Copyright (c) 2001, David H. Hovemeyer <daveho@cs.umd.edu>
-; (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
-; (c) 2008, The V3VEE Project <http://www.v3vee.org>
-; $Revision: 1.1 $
+; -*- fundamental -*-
+;;
+;; Symbol mangling macros
+;; Copyright (c) 2001, David H. Hovemeyer <daveho@cs.umd.edu>
+;;
+;; Permission is hereby granted, free of charge, to any person
+;; obtaining a copy of this software and associated documentation
+;; files (the "Software"), to deal in the Software without restriction,
+;; including without limitation the rights to use, copy, modify, merge,
+;; publish, distribute, sublicense, and/or sell copies of the Software,
+;; and to permit persons to whom the Software is furnished to do so,
+;; subject to the following conditions:
+;;
+;; The above copyright notice and this permission notice shall be
+;; included in all copies or substantial portions of the Software.
+;;
+;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+;; ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+;; TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+;; PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+;; SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+;; FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+;; AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+;; THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+;;
+
+
; This file defines macros for dealing with externally-visible
; symbols that must be mangled for some object file formats.
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include "palacios/vmm_time.h"
#include "palacios/vmm.h"
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <palacios/vmm_util.h>
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
-
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#ifdef __DECODER_TEST__
#include "vmm_decoder.h"
-/* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ * Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
/* Eventually we want to get rid of these */
; -*- fundamental -*-
-
-;; (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
-;; (c) 2008, The V3VEE Project <http://www.v3vee.org>
-
+;;
+;; This file is part of the Palacios Virtual Machine Monitor developed
+;; by the V3VEE Project with funding from the United States National
+;; Science Foundation and the Department of Energy.
+;;
+;; The V3VEE Project is a joint project between Northwestern University
+;; and the University of New Mexico. You can find out more at
+;; http://www.v3vee.org
+;;
+;; Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+;; Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+;; All rights reserved.
+;;
+;; Author: Jack Lange <jarusl@cs.northwestern.edu>
+;;
+;; This is free software. You are permitted to use,
+;; redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+;;
%ifndef VMX_ASM
%define VMX_ASM
--- /dev/null
+#include <xed/v3-xed-compat.h>
+
+
+/* Standard I/O predefined streams
+*/
+static FILE _streams = {0, 0, 0, 0, 0, NULL, NULL, 0, 0};
+FILE *stdin = (&_streams);
+FILE *stdout = (&_streams);
+FILE *stderr = (&_streams);
+
+int fprintf(FILE *file, char *fmt, ...)
+{
+ // PrintDebug("In fprintf!!\n");
+
+ return 0;
+
+}
+
+int printf(char *fmt, ...)
+{
+ // PrintDebug("In fprintf!!\n");
+
+ return 0;
+
+}
+
+int fflush(FILE *stream)
+{
+ //PrintDebug("In fflush!!\n");
+
+ return 0;
+}
+
+void abort(void)
+{
+ //PrintDebug("Abort!!\n");
+
+ //__asm__ __volatile__("trap");
+ //__builtin_unreached();
+
+
+ while(1);
+
+}