export DEVROOT=/path/to/your/vmm-dev
export LOCATION=$DEVROOT/devtools
-cd $DEVROOT/vmm-hack1/build
+cd $DEVROOT/build
export PATH=$PATH:$LOCATION/bin
make world
-This should succeed, leaving you with a vmm.img file.
+This will build a vmm.img floppy image in geekos/build. You can also build a boot ISO image by running:
+
+> make geekos-iso
+
+Which will generate a test.iso image in $DEVROOT/build
--- /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))
+
+
+palacios-full:
+ (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)
+
+
+geekos-full:
+ 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)
+
+
+world: palacios-full geekos-full
+
+
+
+# make ready to boot over PXE
+geekos-pxe:
+ cp $(GEEKOS_BUILD_DIR)/vmm.img /tftpboot/vmm.img
+
+geekos-run:
+ $(QEMU) -m 1024 -serial file:serial.out -cdrom $(GUEST_ISO_DIR)/puppy.iso -fda $(GEEKOS_BUILD_DIR)/vmm.img
+
+geekos-iso:
+ 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
+cp ../geekos/build/vmm.img ./
+/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
+
+
+
+
+#
+#uIP, ON -- used, OFF -- not used
+#
+UIP=OFF
+
+#
+#LWIP, ON -- used, OFF -- not used
+#
+LWIP=OFF
+
+
+#
+# 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
+V3_OBJS := ./palacios/libxed.a ./palacios/libv3vee.a ./palacios/vm_kernel
+
+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
+ 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)
+
+
+lwip:
+ (cd ../src/lwip/build; make clean; make)
+
+
+#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) $(V3_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
int memSizeKB; /* number of KB, as reported by int 15h */
/*Zheng 08/02/2008*/
- unsigned long ramdisk_image; /*ramdisk load addr*/
+ void * ramdisk_image; /*ramdisk load addr*/
unsigned long ramdisk_size;
};
#include <geekos/ktypes.h>
#include <geekos/defs.h>
+
+// to stop the compilation warnings
+extern void Print(const char* fmt, ...);
+extern void Set_Current_Attr(uchar_t attrib);
+
/*
* This struct reflects the contents of the stack when
* a C interrupt handler function is called.
void Wait(struct Thread_Queue* waitQueue);
void Wake_Up(struct Thread_Queue* waitQueue);
void Wake_Up_One(struct Thread_Queue* waitQueue);
+void Wake_Up_Thread(struct Thread_Queue* waitQueue, int pid);
/*
* Pointer to currently executing thread.
#define NE2K_IRQ 11 /* Interrupt channel */
+
+/* Physical Address of Network Card */
+#define PHY_ADDR1 0x52
+#define PHY_ADDR2 0x54
+#define PHY_ADDR3 0x00
+#define PHY_ADDR4 0x12
+#define PHY_ADDR5 0x34
+#define PHY_ADDR6 0x58
+
+
struct NE2K_REGS {
uchar_t cr;
uchar_t isr;
#define GEEKOS_SOCKET_H
#include <geekos/ring_buffer.h>
-#include <uip/uip.h>
#include <geekos/kthread.h>
+#ifdef UIP
+#include <uip/uip.h>
+
typedef enum {WAITING, CLOSED, LISTEN, ESTABLISHED} sock_state_t;
void set_ip_addr(uchar_t addr[4]);
+#endif // UIP
#endif
enum { MUTEX_UNLOCKED, MUTEX_LOCKED };
struct Mutex {
- int state;
- struct Kernel_Thread* owner;
- struct Thread_Queue waitQueue;
+ int state;
+ struct Kernel_Thread* owner;
+ struct Thread_Queue waitQueue;
};
#define MUTEX_INITIALIZER { MUTEX_UNLOCKED, 0, THREAD_QUEUE_INITIALIZER }
void Mutex_Init(struct Mutex* mutex);
void Mutex_Lock(struct Mutex* mutex);
void Mutex_Unlock(struct Mutex* mutex);
+void Mutex_Destroy(struct Mutex *mutex);
void Cond_Init(struct Condition* cond);
void Cond_Wait(struct Condition* cond, struct Mutex* mutex);
+int Cond_Wait_Timeout(struct Condition * cond, struct Mutex * mutex, uint_t ms);
void Cond_Signal(struct Condition* cond);
void Cond_Broadcast(struct Condition* cond);
+void Cond_Destroy(struct Condition *cond);
#define IS_HELD(mutex) \
((mutex)->state == MUTEX_LOCKED && (mutex)->owner == g_currentThread)
--- /dev/null
+/*
+ * GeekOS timer interrupt support
+ * Copyright (c) 2001, David H. Hovemeyer <daveho@cs.umd.edu>
+ * Copyright (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".
+ */
+
+#ifndef GEEKOS_TIMER_H
+#define GEEKOS_TIMER_H
+
+#define TIMER_IRQ 0
+
+extern volatile unsigned long g_numTicks;
+
+typedef void (*timerCallback)(int, void*);
+
+void Init_Timer(void);
+
+void Micro_Delay(int us);
+
+
+typedef struct {
+ int ticks; /* timer code decrements this */
+ int id; /* unqiue id for this timer even */
+ timerCallback callBack; /* Queue to wakeup on timer expire */
+ void * cb_arg; /* Argument to add to callback */
+ int origTicks;
+
+} timerEvent;
+
+int Start_Timer_Secs(int seconds, timerCallback cb, void * arg);
+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);
+int Cancel_Timer(int id);
+
+void Micro_Delay(int us);
+
+unsigned long clock_time(void); //return elipsed millisecs
+
+#endif /* GEEKOS_TIMER_H */
-int geekos_hook_interrupt_new(uint_t irq, void *opaque);
+int geekos_hook_interrupt(struct guest_info * info, uint_t irq);
unsigned int get_cpu_khz();
char *strpbrk(const char *s, const char *accept);
char *strncat(char *s1, const char *s2, size_t limit);
int fprintf(FILE *file, char *fmt, ...);
-//int fflush(FILE *file);
+int fflush(FILE *file);
+int printf(char *fmt, ...);
--- /dev/null
+#ifndef __PING_H__
+#define __PING_H__
+
+void ping_init(void);
+
+#endif /* __PING_H__ */
/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* Author: Adam Dunkels <adam@sics.se>
*
*/
-#ifndef __LWIP_ERR_H__
-#define __LWIP_ERR_H__
-
-#include "lwip/opt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef s8_t err_t;
-
-/* Definitions for error constants. */
-
-#define ERR_OK 0 /* No error, everything OK. */
-#define ERR_MEM -1 /* Out of memory error. */
-#define ERR_BUF -2 /* Buffer error. */
-#define ERR_RTE -3 /* Routing problem. */
-
-#define ERR_IS_FATAL(e) ((e) < ERR_RTE)
-
-#define ERR_ABRT -4 /* Connection aborted. */
-#define ERR_RST -5 /* Connection reset. */
-#define ERR_CLSD -6 /* Connection closed. */
-#define ERR_CONN -7 /* Not connected. */
-
-#define ERR_VAL -8 /* Illegal value. */
-
-#define ERR_ARG -9 /* Illegal argument. */
-
-#define ERR_USE -10 /* Address in use. */
-
-#define ERR_IF -11 /* Low-level netif error */
-#define ERR_ISCONN -12 /* Already connected. */
-
-#define ERR_TIMEOUT -13 /* Timeout. */
-
-#define ERR_INPROGRESS -14 /* Operation in progress */
-
-
-#ifdef LWIP_DEBUG
-extern const char *lwip_strerr(err_t err);
-#else
-#define lwip_strerr(x) ""
-#endif /* LWIP_DEBUG */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_ERR_H__ */
+#ifndef __ARCH_CC_H__
+#define __ARCH_CC_H__
+
+/* Include some files for defining library routines */
+
+#include <string.h>
+#include <geekos/debug.h>
+
+/* Define platform endianness */
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif /* BYTE_ORDER */
+
+/* Define generic types used in lwIP */
+typedef unsigned char u8_t;
+typedef signed char s8_t;
+typedef unsigned short u16_t;
+typedef signed short s16_t;
+typedef unsigned long u32_t;
+typedef signed long s32_t;
+
+typedef u32_t mem_ptr_t;
+
+/* Define (sn)printf formatters for these lwIP types */
+#define U16_F "hu"
+#define S16_F "hd"
+#define X16_F "hx"
+#define U32_F "lu"
+#define S32_F "ld"
+#define X32_F "lx"
+
+/* Compiler hints for packing structures */
+#define PACK_STRUCT_FIELD(x) x __attribute__((packed))
+#define PACK_STRUCT_STRUCT __attribute__((packed))
+#define PACK_STRUCT_BEGIN
+#define PACK_STRUCT_END
+
+/* prototypes for printf() and abort() */
+//#include <stdio.h>
+//#include <stdlib.h>
+/* Plaform specific diagnostic output */
+#define LWIP_PLATFORM_DIAG(x) do {PrintBoth x;} while(0)//do {printf x;} while(0)
+
+#define LWIP_PLATFORM_ASSERT(x) do {printf("Assertion \"%s\" failed at line %d in %s\n", \
+ x, __LINE__, __FILE__); fflush(NULL); abort();} while(0)
+
+#endif /* __ARCH_CC_H__ */
/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* Author: Adam Dunkels <adam@sics.se>
*
*/
-#ifndef __LWIP_INET_H__
-#define __LWIP_INET_H__
+#ifndef __ARCH_PERF_H__
+#define __ARCH_PERF_H__
-#include "lwip/opt.h"
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
+//#include <sys/times.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifdef PERF
+#define PERF_START { \
+ unsigned long __c1l, __c1h, __c2l, __c2h; \
+ __asm__(".byte 0x0f, 0x31" : "=a" (__c1l), "=d" (__c1h))
+#define PERF_STOP(x) __asm__(".byte 0x0f, 0x31" : "=a" (__c2l), "=d" (__c2h)); \
+ perf_print(__c1l, __c1h, __c2l, __c2h, x);}
-u16_t inet_chksum(void *data, u16_t len);
-u16_t inet_chksum_pbuf(struct pbuf *p);
-u16_t inet_chksum_pseudo(struct pbuf *p,
- struct ip_addr *src, struct ip_addr *dest,
- u8_t proto, u32_t proto_len);
+/*#define PERF_START do { \
+ struct tms __perf_start, __perf_end; \
+ times(&__perf_start)
+#define PERF_STOP(x) times(&__perf_end); \
+ perf_print_times(&__perf_start, &__perf_end, x);\
+ } while(0)*/
+#else /* PERF */
+#define PERF_START /* null definition */
+#define PERF_STOP(x) /* null definition */
+#endif /* PERF */
-u32_t inet_addr(const char *cp);
-s8_t inet_aton(const char *cp, struct in_addr *addr);
+#if 0
-#ifndef _MACHINE_ENDIAN_H_
-#ifndef _NETINET_IN_H
-#ifndef _LINUX_BYTEORDER_GENERIC_H
-u16_t htons(u16_t n);
-u16_t ntohs(u16_t n);
-u32_t htonl(u32_t n);
-u32_t ntohl(u32_t n);
-#endif /* _LINUX_BYTEORDER_GENERIC_H */
-#endif /* _NETINET_IN_H */
-#endif /* _MACHINE_ENDIAN_H_ */
+void perf_print(unsigned long c1l, unsigned long c1h,
+ unsigned long c2l, unsigned long c2h,
+ char *key);
-#ifdef __cplusplus
-}
-#endif
+void perf_print_times(struct tms *start, struct tms *end, char *key);
-#endif /* __LWIP_INET_H__ */
+void perf_init(char *fname);
+
+#endif
+#endif /* __ARCH_PERF_H__ */
/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* Author: Adam Dunkels <adam@sics.se>
*
*/
-#ifndef __LWIP_DEF_H__
-#define __LWIP_DEF_H__
+#ifndef __ARCH_SYS_ARCH_H__
+#define __ARCH_SYS_ARCH_H__
-/* this might define NULL already */
-#include "lwip/arch.h"
+//#include <errno.h>
-#define LWIP_MAX(x , y) (((x) > (y)) ? (x) : (y))
-#define LWIP_MIN(x , y) (((x) < (y)) ? (x) : (y))
+#define SYS_MBOX_NULL NULL
+#define SYS_SEM_NULL NULL
-#ifndef NULL
-#define NULL ((void *)0)
-#endif
+typedef u32_t sys_prot_t;
+struct sys_sem;
+typedef struct sys_sem * sys_sem_t;
-#endif /* __LWIP_DEF_H__ */
+struct sys_mbox;
+typedef struct sys_mbox *sys_mbox_t;
+
+struct sys_thread;
+typedef struct sys_thread * sys_thread_t;
+
+#endif /* __ARCH_SYS_ARCH_H__ */
#ifndef __LWIP_IP_ADDR_H__
#define __LWIP_IP_ADDR_H__
-#include "lwip/opt.h"
+#include <lwip/lwip/opt.h>
#ifdef __cplusplus
extern "C" {
#include "arch/cc.h"
+#include "lwip/opt.h"
+
#ifdef __cplusplus
extern "C" {
#endif
#define LWIP_UNUSED_ARG(x) (void)x
#endif /* LWIP_UNUSED_ARG */
+//weird thing, I already defined it in lwipopts.h, does not work? Lei
+#define LWIP_PROVIDE_ERRNO 1
#ifdef LWIP_PROVIDE_ERRNO
* Include user defined options first. Anything not defined in these files
* will be set to standard values. Override anything you dont like!
*/
-#include "lwipopts.h"
+#include <lwip/lwipopts.h>
#include "lwip/debug.h"
/*
* TCP_WND: The size of a TCP window.
*/
#ifndef TCP_WND
-#define TCP_WND 2048
+#define TCP_WND 1024 //2048
#endif
/**
* LWIP_NETIF_API==1: Support netif api (in netifapi.c)
*/
#ifndef LWIP_NETIF_API
-#define LWIP_NETIF_API 0
+#define LWIP_NETIF_API 1
#endif
/**
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define SOCK_RAW 3
-
+
+#if 0 /* already defined in lwip/arch.h */
+/* added by Lei */
+#define ENOOK 0 /* No error, everything OK. */
+#define ENOMEM -1 /* Out of memory error. */
+#define ENOBUFS -2 /* Buffer error. */
+#define EHOSTUNREACH -3 /* Routing problem. */
+#define ECONNABORTED -4 /* Connection aborted. */
+#define ECONNRESET -5 /* Connection reset. */
+#define ESHUTDOWN -6 /* Connection closed. */
+#define ENOTCONN -7 /* Not connected. */
+#define EINVAL -8 /* Illegal value. */
+#define EIO -9 /* Illegal argument. */
+#define EADDRINUSE -10 /* Address in use. */
+#define ETIMEDOUT -13 /* Timeout */
+#define EINPROGRESS -14 /* Operation in progress */
+#endif
+
/*
* Option flags per-socket. These must match the SOF_ flags in ip.h!
*/
struct sockaddr *to, socklen_t tolen);
int lwip_socket(int domain, int type, int protocol);
int lwip_write(int s, const void *dataptr, int size);
-int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
- struct timeval *timeout);
+int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout);
int lwip_ioctl(int s, long cmd, void *argp);
#if LWIP_COMPAT_SOCKETS
--- /dev/null
+/**
+ * @file
+ *
+ * lwIP Options Configuration
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIPOPTS_H__
+#define __LWIPOPTS_H__
+
+/*
+ * Include user defined options first. Anything not defined in these files
+ * will be set to standard values. Override anything you dont like!
+ */
+#include "lwipopts.h"
+#include "lwip/debug.h"
+
+/*
+ -----------------------------------------------
+ ---------- Platform specific locking ----------
+ -----------------------------------------------
+*/
+
+/**
+ * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
+ * critical regions during buffer allocation, deallocation and memory
+ * allocation and deallocation.
+ */
+#define SYS_LIGHTWEIGHT_PROT 0
+
+/**
+ * NO_SYS==1: Provides VERY minimal functionality. Otherwise,
+ * use lwIP facilities.
+ */
+#define NO_SYS 0
+
+/*
+ ------------------------------------
+ ---------- Memory options ----------
+ ------------------------------------
+*/
+
+/**
+ * MEM_ALIGNMENT: should be set to the alignment of the CPU
+ * 4 byte alignment -> #define MEM_ALIGNMENT 4
+ * 2 byte alignment -> #define MEM_ALIGNMENT 2
+ */
+#define MEM_ALIGNMENT 1
+
+/**
+ * MEM_SIZE: the size of the heap memory. If the application will send
+ * a lot of data that needs to be copied, this should be set high.
+ */
+#define MEM_SIZE 1600
+
+/*
+ ------------------------------------------------
+ ---------- Internal Memory Pool Sizes ----------
+ ------------------------------------------------
+*/
+/**
+ * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF).
+ * If the application sends a lot of data out of ROM (or other static memory),
+ * this should be set high.
+ */
+#define MEMP_NUM_PBUF 16
+
+/**
+ * MEMP_NUM_RAW_PCB: Number of raw connection PCBs
+ * (requires the LWIP_RAW option)
+ */
+#define MEMP_NUM_RAW_PCB 4
+
+/**
+ * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
+ * per active UDP "connection".
+ * (requires the LWIP_UDP option)
+ */
+#define MEMP_NUM_UDP_PCB 4
+
+/**
+ * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections.
+ * (requires the LWIP_TCP option)
+ */
+#define MEMP_NUM_TCP_PCB 4
+
+/**
+ * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections.
+ * (requires the LWIP_TCP option)
+ */
+#define MEMP_NUM_TCP_PCB_LISTEN 4
+
+/**
+ * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments.
+ * (requires the LWIP_TCP option)
+ */
+#define MEMP_NUM_TCP_SEG 16
+
+/**
+ * MEMP_NUM_REASSDATA: the number of simultaneously IP packets queued for
+ * reassembly (whole packets, not fragments!)
+ */
+#define MEMP_NUM_REASSDATA 1
+
+/**
+ * MEMP_NUM_ARP_QUEUE: the number of simulateously queued outgoing
+ * packets (pbufs) that are waiting for an ARP request (to resolve
+ * their destination address) to finish.
+ * (requires the ARP_QUEUEING option)
+ */
+#define MEMP_NUM_ARP_QUEUE 2
+
+/**
+ * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts.
+ * (requires NO_SYS==0)
+ */
+#define MEMP_NUM_SYS_TIMEOUT 3
+
+/**
+ * MEMP_NUM_NETBUF: the number of struct netbufs.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#define MEMP_NUM_NETBUF 2
+
+/**
+ * MEMP_NUM_NETCONN: the number of struct netconns.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#define MEMP_NUM_NETCONN 4
+
+/**
+ * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used
+ * for callback/timeout API communication.
+ * (only needed if you use tcpip.c)
+ */
+#define MEMP_NUM_TCPIP_MSG_API 8
+
+/**
+ * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used
+ * for incoming packets.
+ * (only needed if you use tcpip.c)
+ */
+#define MEMP_NUM_TCPIP_MSG_INPKT 8
+
+/**
+ * PBUF_POOL_SIZE: the number of buffers in the pbuf pool.
+ */
+#define PBUF_POOL_SIZE 8
+
+/*
+ ---------------------------------
+ ---------- ARP options ----------
+ ---------------------------------
+*/
+/**
+ * LWIP_ARP==1: Enable ARP functionality.
+ */
+#define LWIP_ARP 1
+
+/*
+ --------------------------------
+ ---------- IP options ----------
+ --------------------------------
+*/
+/**
+ * IP_FORWARD==1: Enables the ability to forward IP packets across network
+ * interfaces. If you are going to run lwIP on a device with only one network
+ * interface, define this to 0.
+ */
+#define IP_FORWARD 0
+
+/**
+ * IP_OPTIONS: Defines the behavior for IP options.
+ * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped.
+ * IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed).
+ */
+#define IP_OPTIONS_ALLOWED 1
+
+/**
+ * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that
+ * this option does not affect outgoing packet sizes, which can be controlled
+ * via IP_FRAG.
+ */
+#define IP_REASSEMBLY 1
+
+/**
+ * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note
+ * that this option does not affect incoming packet sizes, which can be
+ * controlled via IP_REASSEMBLY.
+ */
+#define IP_FRAG 1
+
+/**
+ * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally)
+ * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived
+ * in this time, the whole packet is discarded.
+ */
+#define IP_REASS_MAXAGE 3
+
+/**
+ * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled.
+ * Since the received pbufs are enqueued, be sure to configure
+ * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive
+ * packets even if the maximum amount of fragments is enqueued for reassembly!
+ */
+#define IP_REASS_MAX_PBUFS 4
+
+/**
+ * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP
+ * fragmentation. Otherwise pbufs are allocated and reference the original
+ * packet data to be fragmented.
+*/
+#define IP_FRAG_USES_STATIC_BUF 0
+
+/**
+ * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers.
+ */
+#define IP_DEFAULT_TTL 255
+
+/*
+ ----------------------------------
+ ---------- ICMP options ----------
+ ----------------------------------
+*/
+/**
+ * LWIP_ICMP==1: Enable ICMP module inside the IP stack.
+ * Be careful, disable that make your product non-compliant to RFC1122
+ */
+#define LWIP_ICMP 1
+
+/*
+ ---------------------------------
+ ---------- RAW options ----------
+ ---------------------------------
+*/
+/**
+ * LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
+ */
+#define LWIP_RAW 1
+
+/*
+ ----------------------------------
+ ---------- DHCP options ----------
+ ----------------------------------
+*/
+/**
+ * LWIP_DHCP==1: Enable DHCP module.
+ */
+#define LWIP_DHCP 0
+
+
+/*
+ ------------------------------------
+ ---------- AUTOIP options ----------
+ ------------------------------------
+*/
+/**
+ * LWIP_AUTOIP==1: Enable AUTOIP module.
+ */
+#define LWIP_AUTOIP 0
+
+/*
+ ----------------------------------
+ ---------- SNMP options ----------
+ ----------------------------------
+*/
+/**
+ * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP
+ * transport.
+ */
+#define LWIP_SNMP 0
+
+/*
+ ----------------------------------
+ ---------- IGMP options ----------
+ ----------------------------------
+*/
+/**
+ * LWIP_IGMP==1: Turn on IGMP module.
+ */
+#define LWIP_IGMP 0
+
+/*
+ ----------------------------------
+ ---------- DNS options -----------
+ ----------------------------------
+*/
+/**
+ * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS
+ * transport.
+ */
+#define LWIP_DNS 0
+
+/*
+ ---------------------------------
+ ---------- UDP options ----------
+ ---------------------------------
+*/
+/**
+ * LWIP_UDP==1: Turn on UDP.
+ */
+#define LWIP_UDP 1
+
+/*
+ ---------------------------------
+ ---------- TCP options ----------
+ ---------------------------------
+*/
+/**
+ * LWIP_TCP==1: Turn on TCP.
+ */
+#define LWIP_TCP 1
+
+#define LWIP_LISTEN_BACKLOG 0
+
+/*
+ ----------------------------------
+ ---------- Pbuf options ----------
+ ----------------------------------
+*/
+/**
+ * PBUF_LINK_HLEN: the number of bytes that should be allocated for a
+ * link level header. The default is 14, the standard value for
+ * Ethernet.
+ */
+#define PBUF_LINK_HLEN 16
+
+/**
+ * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is
+ * designed to accomodate single full size TCP frame in one pbuf, including
+ * TCP_MSS, IP header, and link header.
+*
+ */
+#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN)
+
+/*
+ ------------------------------------
+ ---------- LOOPIF options ----------
+ ------------------------------------
+*/
+/**
+ * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c
+ */
+#define LWIP_HAVE_LOOPIF 0
+
+/*
+ ----------------------------------------------
+ ---------- Sequential layer options ----------
+ ----------------------------------------------
+*/
+
+/**
+ * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
+ */
+#define LWIP_NETCONN 1
+
+/*
+ ------------------------------------
+ ---------- Socket options ----------
+ ------------------------------------
+*/
+/**
+ * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
+ */
+#define LWIP_SOCKET 1
+
+/*
+ ----------------------------------------
+ ---------- Statistics options ----------
+ ----------------------------------------
+*/
+/**
+ * LWIP_STATS==1: Enable statistics collection in lwip_stats.
+ */
+#define LWIP_STATS 0
+/*
+ ---------------------------------
+ ---------- PPP options ----------
+ ---------------------------------
+*/
+/**
+ * PPP_SUPPORT==1: Enable PPP.
+ */
+#define PPP_SUPPORT 0
+
+
+/* use errno provided by lwip, Lei */
+#define LWIP_PROVIDE_ERRNO 1
+
+
+/* Misc */
+
+#define LWIP_TIMEVAL_PRIVATE 1
+
+#endif /* __LWIPOPTS_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
*
* \hideinitializer
*/
-typedef unsigned char u8_t;
+//conflict with lwip
+//typedef unsigned char u8_t;
/**
* 16 bit datatype
*
* \hideinitializer
*/
-typedef unsigned short int u16_t;
+//confict with lwip
+//typedef unsigned short int u16_t;
/**
* Statistics datatype
--- /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();
}
-/* int fflush(FILE *stream)
+int printf(char *fmt, ...)
{
- PrintDebug("In fflush!!\n");
+ // PrintDebug("In fprintf!!\n");
+
+ return 0;
+
+}
+
+int fflush(FILE *stream)
+{
+ //PrintDebug("In fflush!!\n");
return 0;
-}*/
+}
void abort(void)
{
* redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
+#include <geekos/debug.h>
-#ifndef __DEBUG_H
-#define __DEBUG_H
-#include <geekos/serial.h>
-#include <geekos/screen.h>
+void PrintBoth(const char * format, ...) {
+ va_list args;
-
-
-
-void PrintBoth(const char * format, ...);
-
-
-
-#endif
+ va_start(args, format);
+ PrintList(format, args);
+ SerialPrintList(format, args);
+ va_end(args);
+}
}
}
+
+
+/*
+ * Wake up a single thread waiting on given wait queue
+ * (if there are any threads waiting). Chooses the highest priority thread.
+ * Interrupts must be disabled!
+ */
+void Wake_Up_Thread(struct Thread_Queue* waitQueue, int pid)
+{
+ struct Kernel_Thread* thread = Lookup_Thread(pid);;
+
+ KASSERT(!Interrupts_Enabled());
+
+
+ if (thread != 0) {
+ Remove_Thread(waitQueue, thread);
+ Make_Runnable(thread);
+ /*Print("Wake_Up_One: waking up %x from %x\n", best, g_currentThread); */
+ }
+}
+
+
+
+
/*
* Allocate a key for accessing thread-local data.
*/
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
Init_Stubs();
- Init_Network();
+ // Init_Network();
// Init_IDE();
*/
struct Page* g_pageList;
-#ifdef RAMDISK_BOOT
-ulong_t g_ramdiskImage;
+void * 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
+ ulong_t initrdAddr = 0;
+ ulong_t initrdEnd = 0;
+
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
*/
+ if (s_ramdiskSize > 0) {
+ initrdAddr = vmmMemEnd;
+ initrdEnd = Round_Up_To_Page(initrdAddr + s_ramdiskSize);
+ PrintBoth("mem.c(%d) Move ramdisk(%dB) from %x to %x", __LINE__, s_ramdiskSize, g_ramdiskImage, initrdAddr);
+ 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));
+ PrintBoth(" done\n");
+ }
- initrdAddr = vmmMemEnd;
- initrdEnd = Round_Up_To_Page(initrdAddr + s_ramdiskSize);
- PrintBoth("mem.c(%d) Move ramdisk(%dB) from %x to %x", __LINE__, s_ramdiskSize, g_ramdiskImage, initrdAddr);
- 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));
- 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
+ */
+ if (s_ramdiskSize > 0) {
+ 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
Add_Page_Range(pageListAddr, pageListEnd, PAGE_KERN); // Page List
Add_Page_Range(pageListEnd, vmmMemEnd, PAGE_AVAIL); // Available VMM memory
-#ifdef RAMDISK_BOOT
- /*
- * Zheng 08/03/2008
- */
- Add_Page_Range(vmmMemEnd, initrdEnd, PAGE_ALLOCATED); //Ramdisk memory area
- // Add_Page_Range(vmmMemEnd, endOfMem, PAGE_VM); // Memory allocated to the VM
- // Until we get a more intelligent memory allocator
- Add_Page_Range(initrdEnd, endOfMem, PAGE_AVAIL); // Memory allocated to the VM
-#else
- Add_Page_Range(vmmMemEnd, endOfMem, PAGE_AVAIL); // Memory allocated to the VM
-#endif
+
+ if (s_ramdiskSize > 0) {
+ /*
+ * Zheng 08/03/2008
+ */
+ Add_Page_Range(vmmMemEnd, initrdEnd, PAGE_ALLOCATED); //Ramdisk memory area
+ // Add_Page_Range(vmmMemEnd, endOfMem, PAGE_VM); // Memory allocated to the VM
+ // Until we get a more intelligent memory allocator
+ Add_Page_Range(initrdEnd, endOfMem, PAGE_AVAIL); // Memory allocated to the VM
+ } else {
+ Add_Page_Range(vmmMemEnd, endOfMem, PAGE_AVAIL); // Memory allocated to the VM
+ }
/* Initialize the kernel heap */
Init_Heap(heapAddr, KERNEL_HEAP_SIZE);
PrintBoth("%lx to %lx - PAGE LIST\n", pageListAddr, pageListEnd - 1);
PrintBoth("%lx to %x - FREE\n", pageListEnd, vmmMemEnd - 1);
-#ifdef RAMDISK_BOOT
- /*
- * Zheng 08/03/2008
- */
- PrintBoth("%lx to %x - RAMDISK\n", vmmMemEnd, initrdEnd - 1);
- PrintBoth("%lx to %x - GUEST_MEMORY (also free)\n", initrdEnd, endOfMem - 1);
-#else
- PrintBoth("%lx to %x - GUEST_MEMORY (also free)\n", vmmMemEnd, endOfMem - 1);
-#endif
+ if (s_ramdiskSize > 0) {
+ /*
+ * Zheng 08/03/2008
+ */
+ PrintBoth("%lx to %x - RAMDISK\n", vmmMemEnd, initrdEnd - 1);
+
+ PrintBoth("%lx to %x - GUEST_MEMORY (also free)\n", initrdEnd, endOfMem - 1);
+ } else {
+ PrintBoth("%lx to %x - GUEST_MEMORY (also free)\n", vmmMemEnd, endOfMem - 1);
+ }
+
}
/*
#include <geekos/irq.h>
#include <geekos/malloc.h>
#include <geekos/string.h>
+
+#ifdef UIP
#include <uip/uip.h>
#include <uip/uip_arp.h>
+#endif
#define DEBUG 1
#define TX_START_BUFF 0x40
cr->ps = 0x01; /* Switch to reg page 1 */
Out_Byte(NE2K_CR, regs->cr);
- /* Set the physical address of the card to 52:54:00:12:34:58 */
- Out_Byte(NE2K_CR+0x01, 0x52);
- Out_Byte(NE2K_CR+0x02, 0x54);
- Out_Byte(NE2K_CR+0x03, 0x00);
- Out_Byte(NE2K_CR+0x04, 0x12);
- Out_Byte(NE2K_CR+0x05, 0x34);
- Out_Byte(NE2K_CR+0x06, 0x58);
+ /* Set the physical address of the card */
+ Out_Byte(NE2K_CR+0x01, PHY_ADDR1);
+ Out_Byte(NE2K_CR+0x02, PHY_ADDR2);
+ Out_Byte(NE2K_CR+0x03, PHY_ADDR3);
+ Out_Byte(NE2K_CR+0x04, PHY_ADDR4);
+ Out_Byte(NE2K_CR+0x05, PHY_ADDR5);
+ Out_Byte(NE2K_CR+0x06, PHY_ADDR6);
/* Set the multicast address register to all 1s; accepts all multicast packets */
uint_t i;
* an ARP packet, which is sent out instead. The original packet will need to be
* retransmitted at some point in the future.
*/
+#ifdef UIP
+
int NE2K_Transmit(uint_t size)
{
uip_arp_out();
return 0;
}
+#endif
+
int NE2K_Send_Packet(uchar_t *packet, uint_t size)
{
struct _CR * cr = (struct _CR*)&(regs->cr);
--- /dev/null
+/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
+/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+
+
+#include <geekos/net.h>
+#include <geekos/socket.h>
+#include <geekos/ne2k.h>
+
+#include <geekos/debug.h>
+
+#ifdef LWIP
+
+#include <lwip/apps/ping.h>
+#include <lwip/lwip/sockets.h>
+#include <lwip/ipv4/lwip/ip_addr.h>
+#include <lwip/netif/ne2kif.h>
+#include <lwip/sys.h>
+#include <lwip/netifapi.h>
+#include <lwip/tcpip.h>
+
+#include <netif/etharp.h>
+
+
+static void
+tcpip_init_done(void *arg)
+{
+ sys_sem_t *sem;
+ sem = arg;
+ sys_sem_signal(*sem);
+}
+
+#endif
+
+void Init_Network() {
+
+ //temporay now we are using lwip sockets
+ // init_socket_layer();
+
+#ifdef LWIP
+
+ struct ip_addr ipaddr, netmask, gateway;
+ sys_sem_t sem;
+ err_t err;
+
+ sem = sys_sem_new(0);
+
+#ifdef LWIP_DEBUG
+ PrintBoth("lwIP: before tcpip_init\n");
+#endif
+
+ tcpip_init(tcpip_init_done, &sem); //initial the whole lwip module
+
+#ifdef LWIP_DEBUG
+ PrintBoth("lwIP: After tcpip_init\n");
+#endif
+
+ sys_sem_wait(sem);
+ sys_sem_free(sem);
+
+ IP4_ADDR(&gateway, 192,168,1,1);
+ IP4_ADDR(&ipaddr, 192,168,1,2);
+ IP4_ADDR(&netmask, 255,255,255,0);
+
+
+ err = netifapi_netif_add(&ne2kif, &ipaddr, &netmask, &gateway,
+ NULL, ne2kif_init, ethernet_input);
+
+ if (err != ERR_OK){
+ PrintBoth("lwip: initial network failed! add netif error %d/n", err);
+ return;
+ }
+
+ netifapi_netif_set_default(&ne2kif);
+
+ //initial a network application
+ ping_init();
+
+#endif
+
+}
+
+
+
+
+#if 0
+void test_network() {
+
+ uchar_t local_addr[4];
+ uchar_t remote_addr[4];
+
+ local_addr[0] = 10;
+ local_addr[1] = 0;
+ local_addr[2] = 2;
+ local_addr[3] = 21;
+
+// set_ip_addr(local_addr);
+
+ remote_addr[0] = 10;
+ remote_addr[1] = 0;
+ remote_addr[2] = 2;
+ remote_addr[3] = 20;
+
+
+ // connect(remote_addr, 4301);
+
+}
+
+#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".
+ */
+
+#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;
+}
#include <geekos/socket.h>
#include <geekos/malloc.h>
#include <geekos/ne2k.h>
+
+#ifdef UIP
+
#include <uip/uip.h>
#include <uip/uip_arp.h>
+
#include <geekos/vmm_stubs.h>
#include <geekos/debug.h>
#include <geekos/timer.h>
-
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
#define MAX_SOCKS 1024
#endif /* UIP_APPCALL */
-
-
static int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt);
-static void periodic_caller(int timer_id);
+static void periodic_caller(int timer_id, void * arg);
void init_socket_layer() {
+
int i = 0;
bool iflag;
sockets[i].state = CLOSED;
}
-
-
//initiate uIP
uip_init();
uip_arp_init();
- //setup device driver
- Init_Ne2k(&Packet_Received);
+ //setup device driver
+ Init_Ne2k(&Packet_Received);
iflag = Begin_Int_Atomic();
- Start_Timer(2, periodic_caller);
+ Start_Timer(2, periodic_caller, NULL);
End_Int_Atomic(iflag);
-
}
-
-
-
void set_ip_addr(uchar_t addr[4]) {
uip_ipaddr_t ipaddr;
uip_ipaddr(ipaddr, addr[0], addr[1], addr[2], addr[3]); /* Local IP address */
uip_sethostaddr(ipaddr);
}
-
static int allocate_socket_fd() {
int i = 0;
}
-
-static void periodic_caller(int timer_id) {
+static void periodic_caller(int timer_id, void * arg) {
int i;
//handle the periodic calls of uIP
return 0;
}
+
+
+#endif /* UIP */
#include <geekos/kassert.h>
#include <geekos/screen.h>
#include <geekos/synch.h>
+#include <geekos/timer.h>
+
+#include <geekos/debug.h>
/*
* NOTES:
}
/*
+ * Destroy Mutex
+ */
+void Mutex_Destroy(struct Mutex* mutex)
+{
+
+
+}
+
+/*
+ * Condition Destroy
+ */
+void Cond_Destroy(struct Condition* cond)
+{
+
+
+}
+
+/*
* Initialize given condition.
*/
void Cond_Init(struct Condition* cond)
g_preemptionDisabled = false;
}
+
+
+struct timeout_data {
+ int pid;
+ int timed_out;
+ struct Thread_Queue * waitQueue;
+};
+
+
+static void timeout_cb(int id, void * arg) {
+ struct timeout_data * to_state = (struct timeout_data *)arg;
+
+ to_state->timed_out = 1;
+ Wake_Up_Thread(to_state->waitQueue, to_state->pid);
+
+}
+
+
+/*
+ * Wait on given condition (protected by given mutex).
+ */
+int Cond_Wait_Timeout(struct Condition* cond, struct Mutex* mutex, uint_t ms)
+{
+ struct timeout_data to_state;
+ struct Kernel_Thread * self = Get_Current();
+
+ to_state.pid = self->pid;
+ to_state.timed_out = 0;
+ to_state.waitQueue = &cond->waitQueue;
+
+ KASSERT(Interrupts_Enabled());
+
+ /* Ensure mutex is held. */
+ KASSERT(IS_HELD(mutex));
+
+ /* Turn off scheduling. */
+ g_preemptionDisabled = true;
+
+
+
+ /*
+ * Release the mutex, but leave preemption disabled.
+ * No other threads will be able to run before this thread
+ * is able to wait. Therefore, this thread will not
+ * miss the eventual notification on the condition.
+ */
+ Mutex_Unlock_Imp(mutex);
+
+
+ Start_Timer_MSecs(ms, timeout_cb, &to_state);
+
+ /*
+ * Atomically reenable preemption and wait in the condition wait queue.
+ * Other threads can run while this thread is waiting,
+ * and eventually one of them will call Cond_Signal() or Cond_Broadcast()
+ * to wake up this thread.
+ * On wakeup, disable preemption again.
+ */
+ Disable_Interrupts();
+ g_preemptionDisabled = false;
+ Wait(&cond->waitQueue);
+ g_preemptionDisabled = true;
+ Enable_Interrupts();
+
+ if (to_state.timed_out == 0) {
+ /* Reacquire the mutex. */
+ Mutex_Lock_Imp(mutex);
+ }
+
+ /* Turn scheduling back on. */
+ g_preemptionDisabled = false;
+
+
+ return to_state.timed_out;
+}
+
/*
* Wake up one thread waiting on the given condition.
* The mutex guarding the condition should be held!
--- /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;
*/
volatile ulong_t g_numTicks;
-ulong_t clock_time(void){
- return g_numTicks;
-}
-
-
/*
* Number of times the spin loop can execute during one timer tick
*/
# define Debug(args...)
#endif
+ulong_t clock_time(void){//in millisec
+ return g_numTicks * (1000/HZ);
+}
+
/* ----------------------------------------------------------------------
* Private functions
* ---------------------------------------------------------------------- */
if (pendingTimerEvents[i].ticks == 0) {
if (timerDebug) Print("timer: event %d expired (%d ticks)\n",
pendingTimerEvents[i].id, pendingTimerEvents[i].origTicks);
- (pendingTimerEvents[i].callBack)(pendingTimerEvents[i].id);
+ (pendingTimerEvents[i].callBack)(pendingTimerEvents[i].id, pendingTimerEvents[i].cb_arg);
pendingTimerEvents[i].ticks = pendingTimerEvents[i].origTicks;
} else {
pendingTimerEvents[i].ticks--;
}
-
+ /* JRL: Broken,
deliver_timer_interrupt_to_vmm(1000000/HZ);
-
+ */
End_IRQ(state);
}
}
-int Start_Timer(int ticks, timerCallback cb)
+int Start_Timer_Secs(int seconds, timerCallback cb, void * arg) {
+ return Start_Timer(seconds * HZ, cb, arg);
+}
+
+
+int Start_Timer_MSecs(int msecs, timerCallback cb, void * arg) {
+ msecs += 10 - (msecs % 10);
+
+ return Start_Timer(msecs * (HZ / 1000), cb, arg);
+}
+
+
+
+int Start_Timer(int ticks, timerCallback cb, void * arg)
{
int ret;
KASSERT(!Interrupts_Enabled());
+ PrintBoth ("there\n");
+
if (timeEventCount == MAX_TIMER_EVENTS) {
return -1;
} else {
ret = nextEventID++;
pendingTimerEvents[timeEventCount].id = ret;
pendingTimerEvents[timeEventCount].callBack = cb;
+ pendingTimerEvents[timeEventCount].cb_arg = arg;
pendingTimerEvents[timeEventCount].ticks = ticks;
pendingTimerEvents[timeEventCount].origTicks = ticks;
timeEventCount++;
}
}
-int Get_Remaing_Timer_Ticks(int id)
+
+int Get_Remaining_Timer_Ticks(int id)
{
int i;
return -1;
}
+
+
+double Get_Remaining_Timer_Secs(int id) {
+ return (Get_Remaining_Timer_Ticks(id) / HZ);
+}
+
+
+int Get_Remaining_Timer_MSecs(int id) {
+ return ((Get_Remaining_Timer_Ticks(id) * 1000) / HZ);
+}
+
+
+
int Cancel_Timer(int id)
{
int i;
Spin(numSpins);
}
+
+
+
+extern void * g_ramdiskImage;
+extern ulong_t s_ramdiskSize;
+
+
#define SPEAKER_PORT 0x61
static inline void VM_Out_Byte(ushort_t port, uchar_t value)
*/
int RunVMM(struct Boot_Info * bootInfo) {
- void * config_data;
-
struct vmm_os_hooks os_hooks;
struct vmm_ctrl_ops vmm_ops;
struct guest_info * vm_info = 0;
-
+ struct v3_vm_config vm_config;
memset(&os_hooks, 0, sizeof(struct vmm_os_hooks));
memset(&vmm_ops, 0, sizeof(struct vmm_ctrl_ops));
+ memset(&vm_config, 0, sizeof(struct v3_vm_config));
os_hooks.print_debug = &SerialPrint;
os_hooks.free = &VMM_Free;
os_hooks.vaddr_to_paddr = &Identity;
os_hooks.paddr_to_vaddr = &Identity;
- os_hooks.hook_interrupt = &geekos_hook_interrupt_new;
+ os_hooks.hook_interrupt = &geekos_hook_interrupt;
os_hooks.ack_irq = &ack_irq;
os_hooks.get_cpu_khz = &get_cpu_khz;
Init_V3(&os_hooks, &vmm_ops);
- extern char _binary_vm_kernel_start;
- PrintBoth(" Guest Load Addr: 0x%x\n", &_binary_vm_kernel_start);
+
+ extern char _binary___palacios_vm_kernel_start;
+ PrintBoth(" Guest Load Addr: 0x%x\n", &_binary___palacios_vm_kernel_start);
+
+ vm_config.vm_kernel = &_binary___palacios_vm_kernel_start;
- config_data = &_binary_vm_kernel_start;
+
+ if (g_ramdiskImage != NULL) {
+ vm_config.use_ramdisk = 1;
+ vm_config.ramdisk = g_ramdiskImage;
+ vm_config.ramdisk_size = s_ramdiskSize;
+ }
+
+
+
vm_info = (vmm_ops).allocate_guest();
PrintBoth("Allocated Guest\n");
- (vmm_ops).config_guest(vm_info, config_data);
+ (vmm_ops).config_guest(vm_info, &vm_config);
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);
#include <geekos/vmm_stubs.h>
#include <geekos/serial.h>
-#include <palacios/vm_guest.h>
#include <geekos/debug.h>
+#include <palacios/vmm.h>
Free(addr);
}
-//
-//
-// This is the interrupt state that the VMM's interrupt handlers need to see
-//
-struct vmm_intr_state {
- uint_t irq;
- uint_t error;
-
- uint_t should_ack; // Should the vmm ack this interrupt, or will
- // the host OS do it?
-
- // This is the value given when the interrupt is hooked.
- // This will never be NULL
- void *opaque;
-};
// This is the function the interface code should call to deliver
// the interrupt to the vmm for handling
-extern void deliver_interrupt_to_vmm(struct vmm_intr_state *state);
-
+//extern int v3_deliver_interrupt(struct guest_info * vm, struct v3_interrupt *intr);
-struct guest_info * irq_map[256];
-void *my_opaque[256];
+struct guest_info * irq_to_guest_map[256];
-static void translate_intr_handler(struct Interrupt_State *state)
-{
-
- struct vmm_intr_state mystate;
+void translate_intr_handler(struct Interrupt_State *state) {
+ struct v3_interrupt intr;
- mystate.irq=state->intNum-32;
- mystate.error=state->errorCode;
- mystate.should_ack=0;
- mystate.opaque=my_opaque[mystate.irq];
+ intr.irq = state->intNum - 32;
+ intr.error = state->errorCode;
+ intr.should_ack = 0;
// PrintBoth("translate_intr_handler: opaque=0x%x\n",mystate.opaque);
- deliver_interrupt_to_vmm(&mystate);
+ v3_deliver_irq(irq_to_guest_map[intr.irq], &intr);
End_IRQ(state);
}
-/*
-static void pic_intr_handler(struct Interrupt_State * state) {
- Begin_IRQ(state);
- struct guest_info * info = irq_map[state->intNum - 32];
- SerialPrint("Interrupt %d (IRQ=%d)\n", state->intNum, state->intNum - 32);
-
- if (info) {
- info->vm_ops.raise_irq(info, state->intNum - 32);
- } else {
- SerialPrint("Interrupt handler error: NULL pointer found, no action taken\n");
- End_IRQ(state);
- return;
- }
-
- // End_IRQ(state);
-}
-*/
-//
-//
-// I really don't know what the heck this is doing... PAD
-//
-/*
-int hook_irq_stub(struct guest_info * info, int irq) {
- if (irq_map[irq]) {
- return -1;
- }
-
- SerialPrint("Hooking IRQ: %d (vm=0x%x)\n", irq, info);
- irq_map[irq] = info;
- volatile void *foo = pic_intr_handler;
-
- // This is disabled for the time being
- foo = 0;
-
-
- Disable_IRQ(irq);
- Install_IRQ(irq, pic_intr_handler);
- Enable_IRQ(irq);
- return 0;
-}
-*/
-int geekos_hook_interrupt_new(uint_t irq, void * opaque)
+int geekos_hook_interrupt(struct guest_info * vm, unsigned int irq)
{
- if (my_opaque[irq]) {
+ if (irq_to_guest_map[irq]) {
PrintBoth("Attempt to hook interrupt that is already hooked\n");
return -1;
} else {
- PrintBoth("Hooked interrupt 0x%x with opaque 0x%x\n",irq,opaque);
- my_opaque[irq]=opaque;
+ PrintBoth("Hooked interrupt 0x%x with opaque 0x%x\n", irq, vm);
+ irq_to_guest_map[irq] = vm;
}
Disable_IRQ(irq);
- Install_IRQ(irq,translate_intr_handler);
+ Install_IRQ(irq, translate_intr_handler);
Enable_IRQ(irq);
return 0;
}
void Init_Stubs() {
- memset(irq_map, 0, sizeof(struct guest_info *) * 256);
+ memset(irq_to_guest_map, 0, sizeof(struct guest_info *) * 256);
}
#include "lwip/udp.h"
#include "lwip/tcpip.h"
+#include "lwip/arch.h"
+
#include <string.h>
#define NUM_SOCKETS MEMP_NUM_NETCONN
struct lwip_select_cb select_cb;
struct lwip_select_cb *p_selcb;
- LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%ld tvusec=%ld)\n",
- maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset,
- timeout ? timeout->tv_sec : -1L, timeout ? timeout->tv_usec : -1L));
+ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%ld tvusec=%ld)\n", maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, timeout?timeout->tv_sec:-1L, timeout?timeout->tv_usec:-1L));
select_cb.next = 0;
select_cb.readset = readset;
LOCK_TCPIP_CORE();
while (1) { /* MAIN Loop */
+
+ PrintBoth("In tcp_thread: main loop\n");
+
sys_mbox_fetch(mbox, (void *)&msg);
+
switch (msg->type) {
#if LWIP_NETCONN
case TCPIP_MSG_API:
--- /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
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/*
+ * Wed Apr 17 16:05:29 EDT 2002 (James Roth)
+ *
+ * - Fixed an unlikely sys_thread_new() race condition.
+ *
+ * - Made current_thread() work with threads which where
+ * not created with sys_thread_new(). This includes
+ * the main thread and threads made with pthread_create().
+ *
+ * - Catch overflows where more than SYS_MBOX_SIZE messages
+ * are waiting to be read. The sys_mbox_post() routine
+ * will block until there is more room instead of just
+ * leaking messages.
+ */
+/*
+ * Modified by Lei Xia (lxia@northwestern.edu) to fit to Palacios, 9/29/2008
+ */
+#include "lwip/debug.h"
+
+#include <string.h>
+
+//#include <palacios/vmm.h>
+#include <geekos/synch.h>
+#include <geekos/kthread.h>
+#include <geekos/debug.h>
+#include <geekos/timer.h>
+#include <geekos/malloc.h>
+
+#include "lwip/sys.h"
+#include "lwip/opt.h"
+#include "lwip/stats.h"
+
+#define UMAX(a, b) ((a) > (b) ? (a) : (b))
+
+static struct sys_thread *threads = NULL;
+
+//static pthread_mutex_t threads_mutex = PTHREAD_MUTEX_INITIALIZER;
+static struct Mutex threads_mutex; // !!!! need to be initiated, void Mutex_Init(struct Mutex* mutex);
+
+struct sys_mbox_msg {
+ struct sys_mbox_msg *next;
+ void *msg;
+};
+
+#define SYS_MBOX_SIZE 128
+
+struct sys_mbox {
+ int first, last;
+ void *msgs[SYS_MBOX_SIZE];
+ struct sys_sem *mail;
+ struct sys_sem *mutex;
+ int wait_send;
+};
+
+struct sys_sem {
+ unsigned int c;
+
+ //pthread_cond_t cond;
+ struct Condition cond;
+
+ //pthread_mutex_t mutex;
+ struct Mutex mutex;
+};
+
+struct sys_thread {
+ struct sys_thread *next;
+ struct sys_timeouts timeouts;
+
+ // pthread_t pthread;
+ struct Kernel_Thread *pthread;
+};
+
+
+//static struct timeval starttime;
+
+//static pthread_mutex_t lwprot_mutex = PTHREAD_MUTEX_INITIALIZER;
+static struct Mutex lwprot_mutex; // !!!! need to be initiated, void Mutex_Init(struct Mutex* mutex);
+
+//static pthread_t lwprot_thread = (pthread_t) 0xDEAD;
+//static struct Kernel_Thread lwprot_thread = (struct Kernel_Thread) 0xDEAD; //!!!!! how to set it to a NULL thread?
+
+//static int lwprot_count = 0;
+
+static struct sys_sem *sys_sem_new_(u8_t count);
+static void sys_sem_free_(struct sys_sem *sem);
+
+static u32_t cond_wait(struct Condition *cond, struct Mutex *mutex, u32_t timeout);
+
+
+/*-----------------------------------------------------------------------------------*/
+static struct sys_thread *
+introduce_thread(struct Kernel_Thread *id /*pthread_t id*/)
+{
+ struct sys_thread *thread;
+
+ thread = (struct sys_thread *)Malloc(sizeof(struct sys_thread));
+
+ if (thread != NULL) {
+ //pthread_mutex_lock(&threads_mutex);
+ Mutex_Lock(&threads_mutex);
+
+ thread->next = threads;
+ thread->timeouts.next = NULL;
+ thread->pthread = id;
+ threads = thread;
+
+ //pthread_mutex_unlock(&threads_mutex);
+ Mutex_Unlock(&threads_mutex);
+ }
+
+ return thread;
+}
+
+static int thread_equal(struct Kernel_Thread *kth1, struct Kernel_Thread *kth2){ //added
+
+ return (kth1->pid == kth2->pid);
+
+}
+
+/*-----------------------------------------------------------------------------------*/
+static struct sys_thread *
+current_thread(void)
+{
+ struct sys_thread *st;
+
+ //pthread_t pt;
+ struct Kernel_Thread *pt;
+
+ //pt = pthread_self();
+ //!!!!!!!!!!!Do these have the same means? Not sure
+ pt = Get_Current();
+
+ //pthread_mutex_lock(&threads_mutex);
+ Mutex_Lock(&threads_mutex);
+
+ for(st = threads; st != NULL; st = st->next) {
+ if (thread_equal(st->pthread, pt)) {
+ //pthread_mutex_unlock(&threads_mutex);
+ Mutex_Unlock(&threads_mutex);
+
+ return st;
+ }
+ }
+
+ //pthread_mutex_unlock(&threads_mutex);
+ Mutex_Unlock(&threads_mutex);
+
+ st = introduce_thread(pt);
+
+ if (!st) {
+ PrintBoth("lwIP error: In current_thread: Can not get current_thread\n");
+ abort();
+ }
+
+ return st;
+}
+
+
+/*-----------------------------------------------------------------------------------*/
+sys_thread_t
+sys_thread_new(char *name, void (* function)(void *arg), void *arg, int stacksize, int prio)
+{
+ //int code;
+ //pthread_t tmp;
+ struct Kernel_Thread *tmp;
+ struct sys_thread *st = NULL;
+
+ //tmp = (struct Kernel_Thread *)Malloc(sizeof(struct Kernel_Thread));
+
+ /* code = pthread_create(&tmp,
+ NULL,
+ (void *(*)(void *))
+ function,
+ arg); */
+
+ tmp = Start_Kernel_Thread(function, arg, PRIORITY_NORMAL , false); //did not consider the priority here
+
+ if (tmp != NULL) {
+ st = introduce_thread(tmp);
+ }
+
+ if (NULL == st) {
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: pthread_create: 0x%x, st = 0x%x",
+ (int)tmp, (int)st));
+ abort();
+ }
+ return st;
+}
+
+
+/*-----------------------------------------------------------------------------------*/
+struct sys_mbox *
+sys_mbox_new(int size)
+{
+ struct sys_mbox *mbox;
+
+ mbox = (struct sys_mbox *)Malloc(sizeof(struct sys_mbox));
+ if (mbox != NULL) {
+ mbox->first = mbox->last = 0;
+ mbox->mail = sys_sem_new_(0);
+ mbox->mutex = sys_sem_new_(1);
+ mbox->wait_send = 0;
+
+#if SYS_STATS
+ lwip_stats.sys.mbox.used++;
+ if (lwip_stats.sys.mbox.used > lwip_stats.sys.mbox.max) {
+ lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used;
+ }
+#endif /* SYS_STATS */
+ }
+ return mbox;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_mbox_free(struct sys_mbox *mbox)
+{
+ if (mbox != SYS_MBOX_NULL) {
+#if SYS_STATS
+ lwip_stats.sys.mbox.used--;
+#endif /* SYS_STATS */
+ sys_sem_wait(mbox->mutex);
+
+ sys_sem_free_(mbox->mail);
+ sys_sem_free_(mbox->mutex);
+ mbox->mail = mbox->mutex = NULL;
+ /* LWIP_DEBUGF("sys_mbox_free: mbox 0x%lx\n", mbox); */
+
+ Free(mbox);
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+err_t
+sys_mbox_trypost(struct sys_mbox *mbox, void *msg)
+{
+ u8_t first;
+
+ sys_sem_wait(mbox->mutex);
+
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: mbox %p msg %p\n",
+ (void *)mbox, (void *)msg));
+
+ if ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE))
+ return ERR_MEM;
+
+ mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
+
+ if (mbox->last == mbox->first) {
+ first = 1;
+ } else {
+ first = 0;
+ }
+
+ mbox->last++;
+
+ if (first) {
+ sys_sem_signal(mbox->mail);
+ }
+
+ sys_sem_signal(mbox->mutex);
+
+ return ERR_OK;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_mbox_post(struct sys_mbox *mbox, void *msg)
+{
+ u8_t first;
+
+ sys_sem_wait(mbox->mutex);
+
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", (void *)mbox, (void *)msg));
+
+ while ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
+ mbox->wait_send++;
+ sys_sem_signal(mbox->mutex);
+ sys_arch_sem_wait(mbox->mail, 0);
+ sys_arch_sem_wait(mbox->mutex, 0);
+ mbox->wait_send--;
+ }
+
+ mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
+
+ if (mbox->last == mbox->first) {
+ first = 1;
+ } else {
+ first = 0;
+ }
+
+ mbox->last++;
+
+ if (first) {
+ sys_sem_signal(mbox->mail);
+ }
+
+ sys_sem_signal(mbox->mutex);
+}
+/*-----------------------------------------------------------------------------------*/
+u32_t
+sys_arch_mbox_tryfetch(struct sys_mbox *mbox, void **msg)
+{
+ sys_arch_sem_wait(mbox->mutex, 0);
+
+ if (mbox->first == mbox->last) {
+ sys_sem_signal(mbox->mutex);
+ return SYS_MBOX_EMPTY;
+ }
+
+ if (msg != NULL) {
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p msg %p\n", (void *)mbox, *msg));
+ *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
+ }
+ else{
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p, null msg\n", (void *)mbox));
+ }
+
+ mbox->first++;
+
+ if (mbox->wait_send) {
+ sys_sem_signal(mbox->mail);
+ }
+
+ sys_sem_signal(mbox->mutex);
+
+ return 0;
+}
+/*-----------------------------------------------------------------------------------*/
+u32_t
+sys_arch_mbox_fetch(struct sys_mbox *mbox, void **msg, u32_t timeout)
+{
+ u32_t time = 0;
+
+ /* The mutex lock is quick so we don't bother with the timeout
+ stuff here. */
+ sys_arch_sem_wait(mbox->mutex, 0);
+
+ while (mbox->first == mbox->last) {
+ sys_sem_signal(mbox->mutex);
+
+ /* We block while waiting for a mail to arrive in the mailbox. We
+ must be prepared to timeout. */
+ if (timeout != 0) {
+ time = sys_arch_sem_wait(mbox->mail, timeout);
+
+ if (time == SYS_ARCH_TIMEOUT) {
+ return SYS_ARCH_TIMEOUT;
+ }
+ } else {
+ sys_arch_sem_wait(mbox->mail, 0);
+ }
+
+ sys_arch_sem_wait(mbox->mutex, 0);
+ }
+
+ if (msg != NULL) {
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", (void *)mbox, *msg));
+ *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
+ }
+ else{
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p, null msg\n", (void *)mbox));
+ }
+
+ mbox->first++;
+
+ if (mbox->wait_send) {
+ sys_sem_signal(mbox->mail);
+ }
+
+ sys_sem_signal(mbox->mutex);
+
+ return time;
+}
+/*-----------------------------------------------------------------------------------*/
+struct sys_sem *
+sys_sem_new(u8_t count)
+{
+#if SYS_STATS
+ lwip_stats.sys.sem.used++;
+ if (lwip_stats.sys.sem.used > lwip_stats.sys.sem.max) {
+ lwip_stats.sys.sem.max = lwip_stats.sys.sem.used;
+ }
+#endif /* SYS_STATS */
+ return sys_sem_new_(count);
+}
+
+/*-----------------------------------------------------------------------------------*/
+static struct sys_sem *
+sys_sem_new_(u8_t count)
+{
+ struct sys_sem *sem;
+
+ sem = (struct sys_sem *)Malloc(sizeof(struct sys_sem));
+ if (sem != NULL) {
+ sem->c = count;
+
+ //pthread_cond_init(&(sem->cond), NULL);
+ Cond_Init(&(sem->cond));
+
+ //pthread_mutex_init(&(sem->mutex), NULL);
+ Mutex_Init(&(sem->mutex));
+ }
+ return sem;
+}
+
+
+/*-----------------------------------------------------------------------------------*/
+static u32_t
+cond_wait(struct Condition *cond, struct Mutex *mutex, u32_t timeout /* timeout is in miliseconds *//* pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout */)
+{
+ ulong_t tdiff, msec;
+
+ /*
+ struct timeval rtime1, rtime2;
+ struct timespec ts;
+ struct timezone tz;
+ */
+ int retval;
+
+ if (timeout > 0) {
+
+ /* Get a timestamp and add the timeout value. */
+ /*gettimeofday(&rtime1, &tz);
+ sec = rtime1.tv_sec;
+ usec = rtime1.tv_usec;
+ usec += timeout % 1000 * 1000;
+ sec += (int)(timeout / 1000) + (int)(usec / 1000000);
+ usec = usec % 1000000;
+ ts.tv_nsec = usec * 1000;
+ ts.tv_sec = sec;
+ */
+ msec = clock_time();
+
+ if (Cond_Wait_Timeout(cond, mutex, timeout) == 1) //return due to timeout
+ retval = ETIMEDOUT;
+
+ //retval = pthread_cond_timedwait(cond, mutex, &ts);
+
+ if (retval == ETIMEDOUT) {
+ return SYS_ARCH_TIMEOUT;
+ } else {
+ /* Calculate for how long we waited for the cond. */
+
+ /*
+ gettimeofday(&rtime2, &tz);
+ tdiff = (rtime2.tv_sec - rtime1.tv_sec) * 1000 +
+ (rtime2.tv_usec - rtime1.tv_usec) / 1000;
+ */
+ tdiff = clock_time();
+
+ tdiff -= msec;
+
+ if (tdiff <= 0) {
+ return 0;
+ }
+
+ return tdiff;
+ }
+ } else {
+ //pthread_cond_wait(cond, mutex);
+ Cond_Wait(cond, mutex);
+
+ return SYS_ARCH_TIMEOUT;
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+u32_t
+sys_arch_sem_wait(struct sys_sem *sem, u32_t timeout)
+{
+ u32_t time = 0;
+
+ //pthread_mutex_lock(&(sem->mutex));
+ Mutex_Lock(&(sem->mutex));
+
+ while (sem->c <= 0) {
+ if (timeout > 0) {
+ time = cond_wait(&(sem->cond), &(sem->mutex), timeout);
+
+ if (time == SYS_ARCH_TIMEOUT) {
+ //pthread_mutex_unlock(&(sem->mutex));
+ Mutex_Unlock(&(sem->mutex));
+
+ return SYS_ARCH_TIMEOUT;
+ }
+ /* pthread_mutex_unlock(&(sem->mutex));
+ return time; */
+ } else { // if timeout = 0
+ cond_wait(&(sem->cond), &(sem->mutex), 0);
+ }
+ }
+ sem->c--;
+ //pthread_mutex_unlock(&(sem->mutex));
+ Mutex_Unlock(&(sem->mutex));
+
+ return time;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_sem_signal(struct sys_sem *sem)
+{
+ //pthread_mutex_lock(&(sem->mutex));
+ Mutex_Lock(&(sem->mutex));
+
+ sem->c++;
+
+ if (sem->c > 1) {
+ sem->c = 1;
+ }
+
+ //pthread_cond_broadcast(&(sem->cond));
+ Cond_Broadcast(&(sem->cond));
+
+ //pthread_mutex_unlock(&(sem->mutex));
+ Mutex_Unlock(&(sem->mutex));
+
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_sem_free(struct sys_sem *sem)
+{
+ if (sem != SYS_SEM_NULL) {
+#if SYS_STATS
+ lwip_stats.sys.sem.used--;
+#endif /* SYS_STATS */
+ sys_sem_free_(sem);
+ }
+}
+
+/*-----------------------------------------------------------------------------------*/
+static void
+sys_sem_free_(struct sys_sem *sem)
+{
+ //pthread_cond_destroy(&(sem->cond));
+ Cond_Destroy(&(sem->cond));
+
+ //pthread_mutex_destroy(&(sem->mutex));
+ Mutex_Destroy(&(sem->mutex));
+
+ Free(sem);
+}
+
+#if 0
+//return time, we do not need this
+/*-----------------------------------------------------------------------------------*/
+unsigned long
+sys_unix_now()
+{
+ struct timeval tv;
+ struct timezone tz;
+ long sec, usec;
+ unsigned long msec;
+ gettimeofday(&tv, &tz);
+
+ sec = tv.tv_sec - starttime.tv_sec;
+ usec = tv.tv_usec - starttime.tv_usec;
+ msec = sec * 1000 + usec / 1000;
+
+ return msec;
+}
+#endif
+
+/*-----------------------------------------------------------------------------------*/
+void
+sys_init()
+{
+ //struct timezone tz;
+ //gettimeofday(&starttime, &tz);
+
+ Mutex_Init(&threads_mutex);
+ Mutex_Init(&lwprot_mutex);
+
+}
+/*-----------------------------------------------------------------------------------*/
+struct sys_timeouts *
+sys_arch_timeouts(void)
+{
+ struct sys_thread *thread;
+
+ thread = current_thread();
+ return &thread->timeouts;
+}
+
+
+/*-----------------------------------------------------------------------------------*/
+/** sys_prot_t sys_arch_protect(void)
+
+This optional function does a "fast" critical region protection and returns
+the previous protection level. This function is only called during very short
+critical regions. An embedded system which supports ISR-based drivers might
+want to implement this function by disabling interrupts. Task-based systems
+might want to implement this by using a mutex or disabling tasking. This
+function should support recursive calls from the same task or interrupt. In
+other words, sys_arch_protect() could be called while already protected. In
+that case the return value indicates that it is already protected.
+
+sys_arch_protect() is only required if your port is supporting an operating
+system.
+*/
+
+#if 0
+sys_prot_t
+sys_arch_protect(void)
+{
+ /* Note that for the UNIX port, we are using a lightweight mutex, and our
+ * own counter (which is locked by the mutex). The return code is not actually
+ * used. */
+ if (lwprot_thread != current_thread() /*lwprot_thread != pthread_self()*/)
+ {
+ /* We are locking the mutex where it has not been locked before *
+ * or is being locked by another thread */
+ Mutex_Lock(&lwprot_mutex);
+ lwprot_thread = current_thread();
+ lwprot_count = 1;
+ }
+ else
+ /* It is already locked by THIS thread */
+ lwprot_count++;
+ return 0;
+}
+/*-----------------------------------------------------------------------------------*/
+/** void sys_arch_unprotect(sys_prot_t pval)
+
+This optional function does a "fast" set of critical region protection to the
+value specified by pval. See the documentation for sys_arch_protect() for
+more information. This function is only required if your port is supporting
+an operating system.
+*/
+void
+sys_arch_unprotect(sys_prot_t pval)
+{
+ if (lwprot_thread == current_thread())
+ {
+ if (--lwprot_count == 0)
+ {
+ lwprot_thread = (struc Kernel_Thread) 0xDEAD;
+ Mutex_Unlock(&lwprot_mutex);
+ }
+ }
+}
+#endif
+
+/*-----------------------------------------------------------------------------------*/
+
+#ifndef MAX_JIFFY_OFFSET
+#define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)
+#endif
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#if 0
+unsigned long
+sys_jiffies(void)
+{
+ struct timeval tv;
+ unsigned long sec = tv.tv_sec;
+ long usec = tv.tv_usec;
+
+ gettimeofday(&tv,NULL);
+
+ if (sec >= (MAX_JIFFY_OFFSET / HZ))
+ return MAX_JIFFY_OFFSET;
+ usec += 1000000L / HZ - 1;
+ usec /= 1000000L / HZ;
+ return HZ * sec + usec;
+}
+#endif
+
+#if PPP_DEBUG
+
+#include <geekos/serial.h>
+
+void ppp_trace(int level, const char *format, ...)
+{
+ va_list args;
+
+ (void)level;
+ va_start(args, format);
+
+ //vprintf(format, args);
+ PrintDebug(format, args);
+
+ va_end(args);
+}
+#endif
--- /dev/null
+#
+# Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
+# All rights reserved.
+#
+# 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.
+#
+# Author: Adam Dunkels <adam@sics.se>
+#
+
+## modified by Lei Xia
+
+PROJECT_ROOT=../../../
+
+#Set this to where you have the lwip core module
+LWIPDIR=..
+
+CC_PREFIX := $(PROJECT_ROOT)../devtools/i386/bin/i386-elf-
+CC=$(CC_PREFIX)gcc
+CFLAGS=-g -Wall -fpic -DIPv4 -DLWIP_DEBUG
+ARCHIVE=ar
+
+CFLAGS:=$(CFLAGS) \
+ -I$(PROJECT_ROOT)include/ -I$(PROJECT_ROOT)include/lwip -I$(PROJECT_ROOT)include/lwip/ipv4 -I$(PROJECT_ROOT)include/libc
+
+# COREFILES, CORE4FILES: The minimum set of files needed for lwIP.
+COREFILES=$(LWIPDIR)/core/mem.c $(LWIPDIR)/core/memp.c $(LWIPDIR)/core/netif.c \
+ $(LWIPDIR)/core/pbuf.c $(LWIPDIR)/core/stats.c $(LWIPDIR)/core/sys.c \
+ $(LWIPDIR)/core/tcp.c $(LWIPDIR)/core/tcp_in.c $(LWIPDIR)/core/raw.c\
+ $(LWIPDIR)/core/tcp_out.c $(LWIPDIR)/core/udp.c $(LWIPDIR)/core/init.c
+CORE4FILES=$(LWIPDIR)/core/ipv4/icmp.c $(LWIPDIR)/core/ipv4/ip.c \
+ $(LWIPDIR)/core/ipv4/inet.c $(LWIPDIR)/core/ipv4/ip_addr.c \
+ $(LWIPDIR)/core/ipv4/inet_chksum.c $(LWIPDIR)/core/ipv4/ip_frag.c
+
+
+# APIFILES: The files which implement the sequential and socket APIs.
+APIFILES=$(LWIPDIR)/api/api_lib.c $(LWIPDIR)/api/api_msg.c $(LWIPDIR)/api/tcpip.c \
+ $(LWIPDIR)/api/err.c $(LWIPDIR)/api/sockets.c $(LWIPDIR)/api/netbuf.c $(LWIPDIR)/api/netdb.c $(LWIPDIR)/api/netifapi.c
+
+# NETIFFILES: Files implementing various generic network interface functions.'
+NETIFFILES=$(LWIPDIR)/netif/loopif.c $(LWIPDIR)/netif/ne2kif.c $(LWIPDIR)/netif/etharp.c
+
+# ARCHFILES: Architecture specific files.
+ARCHFILES=$(LWIPDIR)/arch/sys_arch.c
+
+# APPFILES: Application files
+APPFILES=$(LWIPDIR)/apps/ping.c
+
+# LWIPFILES: All the above.
+LWIPFILES=$(COREFILES) $(CORE4FILES) $(APIFILES) $(NETIFFILES) $(ARCHFILES) $(APPFILES)
+LWIPFILESW=$(wildcard $(LWIPFILES))
+LWIPOBJS=$(notdir $(LWIPFILESW:.c=.o))
+
+# LWIPLIB=lwip.o
+
+%.o:
+ $(CC) $(CFLAGS) -c $(LWIPFILES)
+
+all: $(LWIPOBJS)
+ cp *.o $(PROJECT_ROOT)build/lwip/
+
+.PHONY: all
+
+clean:
+ rm -f *.o .depend*
+
+depend dep: .depend
+
+include .depend
+
+# $(LWIPLIB): $(LWIPOBJS)
+# $(CC) -g -nostartfiles -shared -static $^ -o $@
+
+.depend: $(LWIPFILES)
+ $(CC) $(CFLAGS) -MM $^ > .depend || rm -f .depend
if (TCP_SNDLOWAT > TCP_SND_BUF)
LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than or equal to TCP_SND_BUF.\n"));
if (TCP_WND > (PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE))
- LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE\n"));
+ LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE: %d\n", (PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE)));
if (TCP_WND < TCP_MSS)
LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is smaller than MSS\n"));
#endif /* LWIP_TCP */
--- /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
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: chap.h,v 1.1 2008/09/12 20:16:42 jarusl Exp $
+ * $Id: chap.h,v 1.4 2007/12/19 20:47:22 fbernon Exp $
*/
#ifndef CHAP_H
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: chpms.h,v 1.1 2008/09/12 20:16:42 jarusl Exp $
+ * $Id: chpms.h,v 1.5 2007/12/19 20:47:23 fbernon Exp $
*/
#ifndef CHPMS_H
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: fsm.h,v 1.1 2008/09/12 20:16:42 jarusl Exp $
+ * $Id: fsm.h,v 1.4 2007/12/19 20:47:23 fbernon Exp $
*/
#ifndef FSM_H
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: ipcp.h,v 1.1 2008/09/12 20:16:42 jarusl Exp $
+ * $Id: ipcp.h,v 1.3 2007/12/19 20:47:23 fbernon Exp $
*/
#ifndef IPCP_H
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: lcp.h,v 1.1 2008/09/12 20:16:42 jarusl Exp $
+ * $Id: lcp.h,v 1.3 2007/12/19 20:47:23 fbernon Exp $
*/
#ifndef LCP_H
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: magic.h,v 1.1 2008/09/12 20:16:42 jarusl Exp $
+ * $Id: magic.h,v 1.2 2007/12/02 22:35:55 fbernon Exp $
*/
#ifndef MAGIC_H
/*
* Definitions for tcp compression routines.
*
- * $Id: vj.h,v 1.1 2008/09/12 20:16:42 jarusl Exp $
+ * $Id: vj.h,v 1.5 2007/12/19 20:47:23 fbernon Exp $
*
* Copyright (c) 1989 Regents of the University of California.
* All rights reserved.
uip_flags = 0;
return;
}
+
/*---------------------------------------------------------------------------*/
+/* replicate defined in lwip.c,
u16_t
htons(u16_t val)
{
return HTONS(val);
}
+*/
+
/*---------------------------------------------------------------------------*/
void
uip_send(const void *data, int len)
#
# 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
-#
-TCPSTACK=UIP
-#
-#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
-
-
-# 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
+ALL_TARGETS := vmm vm_kernel
-# 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)
-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)
+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_OBJS := $(TCPSTACK_C_OBJS)
# This section defines programs that are used to build GeekOS.
# ----------------------------------------------------------------------
+
+V3_ARCH := __V3_32BIT__
+#V3_ARCH := __V3_64BIT__
+
# Uncomment if cross compiling
-TARGET_CC_PREFIX := $(PROJECT_ROOT)/../devtools/i386/bin/i386-elf-
+#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)gcc -m32
#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
+GENERAL_OPTS := -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)
+CC_VMM_OPTS := -g -I$(PROJECT_ROOT)/include -D__V3VEE__ -D$(V3_ARCH) $(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) $< -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_VMM_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
vgabios_link:
ln -s -f ../src/vmboot/vgabios/VGABIOS-lgpl-latest.bin vgabios
+force_lwip:
+ (cd ../src/lwip/build; make clean; make)
+
force_rombios: rombios_link
(cd ../src/vmboot/rombios; make clean; make)
force_payload: force_rombios force_vgabios
../scripts/make_payload.pl payload_layout.txt vm_kernel
-inter1: force_payload
+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' \
+
/*
* This file is part of the Palacios Virtual Machine Monitor developed
* by the V3VEE Project with funding from the United States National
#ifndef __DEVICES_CDROM_H_
#define __DEVICES_CDROM_H_
-#include <geekos/ktypes.h>
-typedef unsigned int rd_bool;
-typedef uchar_t Bit8u;
-typedef ushort_t Bit16u;
-typedef uint_t Bit32u;
-typedef ullong_t Bit64u;
+#ifdef __V3VEE__
+
+#include <devices/ramdisk.h>
+#include <devices/ide.h>
+#include <palacios/vmm_types.h>
-#define uint8 Bit8u
-#define uint16 Bit16u
-#define uint32 Bit32u
-struct cdrom_interface;
-struct cdrom_ops {
-
- void (*init)(struct cdrom_interface *cdrom);
+
+struct cdrom_ops {
/*
* Load CD-ROM. Returns false if CD is not ready.
*/
- rd_bool (*insert_cdrom)(struct cdrom_interface *cdrom, char *dev /*= NULL*/);
+ rd_bool (*insert_cdrom)(void * private_data);
/*
* Logically eject the CD.
*/
- void (*eject_cdrom)(struct cdrom_interface *cdrom);
+ void (*eject_cdrom)(void * private_data);
/*
* 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)(void * private_data, uchar_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)(void * private_data);
/*
* Read a single block from the CD
*/
- void (*read_block)(struct cdrom_interface *cdrom, uint8* buf, int lba);
+ void (*read_block)(void * private_data, uchar_t * buf, int lba);
/*
* Start (spin up) the CD.
*/
- int (*start_cdrom)(struct cdrom_interface *cdrom);
+ int (*start_cdrom)(void * private_data);
+
+ void (*set_LBA)(void * private_data, uchar_t lba);
};
-struct cdrom_interface {
- struct cdrom_ops ops;
- ulong_t fd; //memory address
- ulong_t capacity_B;
- ulong_t head; //current position
+struct vm_device * v3_create_cdrom(struct vm_device * ramdisk_dev, void * ramdisk, uint_t ramdisk_size);
- uchar_t lba;
- char *path; //for ramdisk, NULL
- int using_file; //no
-};
-void init_cdrom(struct cdrom_interface *cdrom);
+#endif // !__V3VEE__
#endif
-
/*
* This file is part of the Palacios Virtual Machine Monitor developed
* by the V3VEE Project with funding from the United States National
* 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
#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 ushort_t Bit16u;
typedef uint32_t Bit32u;
typedef uint64_t Bit64u;
-#endif
+
#define MAX_ATA_CHANNEL 4
rd_bool ready;
rd_bool locked;
- struct cdrom_interface * cd;
+ struct cdrom_ops * cd;
uint32_t capacity;
int next_lba;
struct sense_info_t sense;
struct atapi_t atapi;
+
+ /* JRL */
+ void * private_data;
+
Bit8u model_no[41];
};
#endif
+
+#if 0
+
+// 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);
+
+
+#endif
#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
+struct cdrom_ops;
-#define MAX_ATA_CHANNEL 4
-#define RD_LITTLE_ENDIAN
+int v3_ramdisk_register_cdrom(struct vm_device * ide_dev, uint_t busID, uint_t driveID, struct cdrom_ops * cd, void * private_data);
-#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
+++ /dev/null
-/*
- * GeekOS timer interrupt support
- * Copyright (c) 2001, David H. Hovemeyer <daveho@cs.umd.edu>
- * Copyright (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".
- */
-
-#ifndef GEEKOS_TIMER_H
-#define GEEKOS_TIMER_H
-
-#define TIMER_IRQ 0
-
-extern volatile ulong_t g_numTicks;
-
-typedef void (*timerCallback)(int);
-
-void Init_Timer(void);
-
-void Micro_Delay(int us);
-
-
-typedef struct {
- int ticks; /* timer code decrements this */
- int id; /* unqiue id for this timer even */
- timerCallback callBack; /* Queue to wakeup on timer expire */
- int origTicks;
-} timerEvent;
-
-int Start_Timer(int ticks, timerCallback);
-int Get_Remaing_Timer_Ticks(int id);
-int Cancel_Timer(int id);
-
-
-void Micro_Delay(int us);
-
-#endif /* GEEKOS_TIMER_H */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_IP_ADDR_H__
-#define __LWIP_IP_ADDR_H__
-
-#include "lwip/opt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct ip_addr {
- PACK_STRUCT_FIELD(u32_t addr);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-/*
- * struct ipaddr2 is used in the definition of the ARP packet format in
- * order to support compilers that don't have structure packing.
- */
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct ip_addr2 {
- PACK_STRUCT_FIELD(u16_t addrw[2]);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-/* For compatibility with BSD code */
-struct in_addr {
- u32_t s_addr;
-};
-
-struct netif;
-
-extern const struct ip_addr ip_addr_any;
-extern const struct ip_addr ip_addr_broadcast;
-
-/** IP_ADDR_ can be used as a fixed IP address
- * for the wildcard and the broadcast address
- */
-#define IP_ADDR_ANY ((struct ip_addr *)&ip_addr_any)
-#define IP_ADDR_BROADCAST ((struct ip_addr *)&ip_addr_broadcast)
-
-#define INADDR_NONE ((u32_t)0xffffffffUL) /* 255.255.255.255 */
-#define INADDR_LOOPBACK ((u32_t)0x7f000001UL) /* 127.0.0.1 */
-
-/* Definitions of the bits in an Internet address integer.
-
- On subnets, host and network parts are found according to
- the subnet mask, not these masks. */
-
-#define IN_CLASSA(a) ((((u32_t)(a)) & 0x80000000UL) == 0)
-#define IN_CLASSA_NET 0xff000000
-#define IN_CLASSA_NSHIFT 24
-#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET)
-#define IN_CLASSA_MAX 128
-
-#define IN_CLASSB(a) ((((u32_t)(a)) & 0xc0000000UL) == 0x80000000UL)
-#define IN_CLASSB_NET 0xffff0000
-#define IN_CLASSB_NSHIFT 16
-#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET)
-#define IN_CLASSB_MAX 65536
-
-#define IN_CLASSC(a) ((((u32_t)(a)) & 0xe0000000UL) == 0xc0000000UL)
-#define IN_CLASSC_NET 0xffffff00
-#define IN_CLASSC_NSHIFT 8
-#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET)
-
-#define IN_CLASSD(a) (((u32_t)(a) & 0xf0000000UL) == 0xe0000000UL)
-#define IN_CLASSD_NET 0xf0000000 /* These ones aren't really */
-#define IN_CLASSD_NSHIFT 28 /* net and host fields, but */
-#define IN_CLASSD_HOST 0x0fffffff /* routing needn't know. */
-#define IN_MULTICAST(a) IN_CLASSD(a)
-
-#define IN_EXPERIMENTAL(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL)
-#define IN_BADCLASS(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL)
-
-#define IN_LOOPBACKNET 127 /* official! */
-
-#define IP4_ADDR(ipaddr, a,b,c,d) \
- (ipaddr)->addr = htonl(((u32_t)((a) & 0xff) << 24) | \
- ((u32_t)((b) & 0xff) << 16) | \
- ((u32_t)((c) & 0xff) << 8) | \
- (u32_t)((d) & 0xff))
-
-#define ip_addr_set(dest, src) (dest)->addr = \
- ((src) == NULL? 0:\
- (src)->addr)
-/**
- * Determine if two address are on the same network.
- *
- * @arg addr1 IP address 1
- * @arg addr2 IP address 2
- * @arg mask network identifier mask
- * @return !0 if the network identifiers of both address match
- */
-#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \
- (mask)->addr) == \
- ((addr2)->addr & \
- (mask)->addr))
-#define ip_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr)
-
-#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == 0)
-
-u8_t ip_addr_isbroadcast(struct ip_addr *, struct netif *);
-
-#define ip_addr_ismulticast(addr1) (((addr1)->addr & ntohl(0xf0000000UL)) == ntohl(0xe0000000UL))
-
-#define ip_addr_islinklocal(addr1) (((addr1)->addr & ntohl(0xffff0000UL)) == ntohl(0xa9fe0000UL))
-
-#define ip_addr_debug_print(debug, ipaddr) \
- LWIP_DEBUGF(debug, ("%"U16_F".%"U16_F".%"U16_F".%"U16_F, \
- ipaddr ? (u16_t)(ntohl((ipaddr)->addr) >> 24) & 0xff : 0, \
- ipaddr ? (u16_t)(ntohl((ipaddr)->addr) >> 16) & 0xff : 0, \
- ipaddr ? (u16_t)(ntohl((ipaddr)->addr) >> 8) & 0xff : 0, \
- ipaddr ? (u16_t)ntohl((ipaddr)->addr) & 0xff : 0))
-
-/* These are cast to u16_t, with the intent that they are often arguments
- * to printf using the U16_F format from cc.h. */
-#define ip4_addr1(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 24) & 0xff)
-#define ip4_addr2(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 16) & 0xff)
-#define ip4_addr3(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 8) & 0xff)
-#define ip4_addr4(ipaddr) ((u16_t)(ntohl((ipaddr)->addr)) & 0xff)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_IP_ADDR_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_ARCH_H__
-#define __LWIP_ARCH_H__
-
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
-#endif
-
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
-#endif
-
-#include "arch/cc.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef PACK_STRUCT_BEGIN
-#define PACK_STRUCT_BEGIN
-#endif /* PACK_STRUCT_BEGIN */
-
-#ifndef PACK_STRUCT_END
-#define PACK_STRUCT_END
-#endif /* PACK_STRUCT_END */
-
-#ifndef PACK_STRUCT_FIELD
-#define PACK_STRUCT_FIELD(x) x
-#endif /* PACK_STRUCT_FIELD */
-
-
-#ifndef LWIP_UNUSED_ARG
-#define LWIP_UNUSED_ARG(x) (void)x
-#endif /* LWIP_UNUSED_ARG */
-
-
-#ifdef LWIP_PROVIDE_ERRNO
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* I/O error */
-#define ENXIO 6 /* No such device or address */
-#define E2BIG 7 /* Arg list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file number */
-#define ECHILD 10 /* No child processes */
-#define EAGAIN 11 /* Try again */
-#define ENOMEM 12 /* Out of memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#define ENOTBLK 15 /* Block device required */
-#define EBUSY 16 /* Device or resource busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* No such device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* File table overflow */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Not a typewriter */
-#define ETXTBSY 26 /* Text file busy */
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-#define EDOM 33 /* Math argument out of domain of func */
-#define ERANGE 34 /* Math result not representable */
-#define EDEADLK 35 /* Resource deadlock would occur */
-#define ENAMETOOLONG 36 /* File name too long */
-#define ENOLCK 37 /* No record locks available */
-#define ENOSYS 38 /* Function not implemented */
-#define ENOTEMPTY 39 /* Directory not empty */
-#define ELOOP 40 /* Too many symbolic links encountered */
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define ENOMSG 42 /* No message of desired type */
-#define EIDRM 43 /* Identifier removed */
-#define ECHRNG 44 /* Channel number out of range */
-#define EL2NSYNC 45 /* Level 2 not synchronized */
-#define EL3HLT 46 /* Level 3 halted */
-#define EL3RST 47 /* Level 3 reset */
-#define ELNRNG 48 /* Link number out of range */
-#define EUNATCH 49 /* Protocol driver not attached */
-#define ENOCSI 50 /* No CSI structure available */
-#define EL2HLT 51 /* Level 2 halted */
-#define EBADE 52 /* Invalid exchange */
-#define EBADR 53 /* Invalid request descriptor */
-#define EXFULL 54 /* Exchange full */
-#define ENOANO 55 /* No anode */
-#define EBADRQC 56 /* Invalid request code */
-#define EBADSLT 57 /* Invalid slot */
-
-#define EDEADLOCK EDEADLK
-
-#define EBFONT 59 /* Bad font file format */
-#define ENOSTR 60 /* Device not a stream */
-#define ENODATA 61 /* No data available */
-#define ETIME 62 /* Timer expired */
-#define ENOSR 63 /* Out of streams resources */
-#define ENONET 64 /* Machine is not on the network */
-#define ENOPKG 65 /* Package not installed */
-#define EREMOTE 66 /* Object is remote */
-#define ENOLINK 67 /* Link has been severed */
-#define EADV 68 /* Advertise error */
-#define ESRMNT 69 /* Srmount error */
-#define ECOMM 70 /* Communication error on send */
-#define EPROTO 71 /* Protocol error */
-#define EMULTIHOP 72 /* Multihop attempted */
-#define EDOTDOT 73 /* RFS specific error */
-#define EBADMSG 74 /* Not a data message */
-#define EOVERFLOW 75 /* Value too large for defined data type */
-#define ENOTUNIQ 76 /* Name not unique on network */
-#define EBADFD 77 /* File descriptor in bad state */
-#define EREMCHG 78 /* Remote address changed */
-#define ELIBACC 79 /* Can not access a needed shared library */
-#define ELIBBAD 80 /* Accessing a corrupted shared library */
-#define ELIBSCN 81 /* .lib section in a.out corrupted */
-#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
-#define ELIBEXEC 83 /* Cannot exec a shared library directly */
-#define EILSEQ 84 /* Illegal byte sequence */
-#define ERESTART 85 /* Interrupted system call should be restarted */
-#define ESTRPIPE 86 /* Streams pipe error */
-#define EUSERS 87 /* Too many users */
-#define ENOTSOCK 88 /* Socket operation on non-socket */
-#define EDESTADDRREQ 89 /* Destination address required */
-#define EMSGSIZE 90 /* Message too long */
-#define EPROTOTYPE 91 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 92 /* Protocol not available */
-#define EPROTONOSUPPORT 93 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
-#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
-#define EPFNOSUPPORT 96 /* Protocol family not supported */
-#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
-#define EADDRINUSE 98 /* Address already in use */
-#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
-#define ENETDOWN 100 /* Network is down */
-#define ENETUNREACH 101 /* Network is unreachable */
-#define ENETRESET 102 /* Network dropped connection because of reset */
-#define ECONNABORTED 103 /* Software caused connection abort */
-#define ECONNRESET 104 /* Connection reset by peer */
-#define ENOBUFS 105 /* No buffer space available */
-#define EISCONN 106 /* Transport endpoint is already connected */
-#define ENOTCONN 107 /* Transport endpoint is not connected */
-#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
-#define ETOOMANYREFS 109 /* Too many references: cannot splice */
-#define ETIMEDOUT 110 /* Connection timed out */
-#define ECONNREFUSED 111 /* Connection refused */
-#define EHOSTDOWN 112 /* Host is down */
-#define EHOSTUNREACH 113 /* No route to host */
-#define EALREADY 114 /* Operation already in progress */
-#define EINPROGRESS 115 /* Operation now in progress */
-#define ESTALE 116 /* Stale NFS file handle */
-#define EUCLEAN 117 /* Structure needs cleaning */
-#define ENOTNAM 118 /* Not a XENIX named type file */
-#define ENAVAIL 119 /* No XENIX semaphores available */
-#define EISNAM 120 /* Is a named type file */
-#define EREMOTEIO 121 /* Remote I/O error */
-#define EDQUOT 122 /* Quota exceeded */
-
-#define ENOMEDIUM 123 /* No medium found */
-#define EMEDIUMTYPE 124 /* Wrong medium type */
-
-
-#define ENSROK 0 /* DNS server returned answer with no data */
-#define ENSRNODATA 160 /* DNS server returned answer with no data */
-#define ENSRFORMERR 161 /* DNS server claims query was misformatted */
-#define ENSRSERVFAIL 162 /* DNS server returned general failure */
-#define ENSRNOTFOUND 163 /* Domain name not found */
-#define ENSRNOTIMP 164 /* DNS server does not implement requested operation */
-#define ENSRREFUSED 165 /* DNS server refused query */
-#define ENSRBADQUERY 166 /* Misformatted DNS query */
-#define ENSRBADNAME 167 /* Misformatted domain name */
-#define ENSRBADFAMILY 168 /* Unsupported address family */
-#define ENSRBADRESP 169 /* Misformatted DNS reply */
-#define ENSRCONNREFUSED 170 /* Could not contact DNS servers */
-#define ENSRTIMEOUT 171 /* Timeout while contacting DNS servers */
-#define ENSROF 172 /* End of file */
-#define ENSRFILE 173 /* Error reading file */
-#define ENSRNOMEM 174 /* Out of memory */
-#define ENSRDESTRUCTION 175 /* Application terminated lookup */
-#define ENSRQUERYDOMAINTOOLONG 176 /* Domain name is too long */
-#define ENSRCNAMELOOP 177 /* Domain name is too long */
-
-#ifndef errno
-extern int errno;
-#endif
-
-#endif /* LWIP_PROVIDE_ERRNO */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_ARCH_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-
-#ifndef __LWIP_SOCKETS_H__
-#define __LWIP_SOCKETS_H__
-
-#include "lwip/opt.h"
-
-#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/ip_addr.h"
-#include "lwip/inet.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* members are in network byte order */
-struct sockaddr_in {
- u8_t sin_len;
- u8_t sin_family;
- u16_t sin_port;
- struct in_addr sin_addr;
- char sin_zero[8];
-};
-
-struct sockaddr {
- u8_t sa_len;
- u8_t sa_family;
- char sa_data[14];
-};
-
-#ifndef socklen_t
-# define socklen_t u32_t
-#endif
-
-/* Socket protocol types (TCP/UDP/RAW) */
-#define SOCK_STREAM 1
-#define SOCK_DGRAM 2
-#define SOCK_RAW 3
-
-/*
- * Option flags per-socket. These must match the SOF_ flags in ip.h!
- */
-#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* Unimplemented: allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */
-#define SO_BROADCAST 0x0020 /* Unimplemented: permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */
-#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */
-
-#define SO_DONTLINGER ((int)(~SO_LINGER))
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* Unimplemented: send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */
-#define SO_NO_CHECK 0x100a /* don't create UDP checksum */
-
-
-/*
- * Structure used for manipulating linger option.
- */
-struct linger {
- int l_onoff; /* option on/off */
- int l_linger; /* linger time */
-};
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xfff /* options for socket level */
-
-
-#define AF_UNSPEC 0
-#define AF_INET 2
-#define PF_INET AF_INET
-#define PF_UNSPEC AF_UNSPEC
-
-#define IPPROTO_IP 0
-#define IPPROTO_TCP 6
-#define IPPROTO_UDP 17
-#define IPPROTO_UDPLITE 136
-
-#define INADDR_ANY 0
-#define INADDR_BROADCAST 0xffffffff
-
-/* Flags we can use with send and recv. */
-#define MSG_PEEK 0x01 /* Peeks at an incoming message */
-#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */
-#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */
-#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */
-#define MSG_MORE 0x10 /* Sender will send more */
-
-
-/*
- * Options for level IPPROTO_IP
- */
-#define IP_TOS 1
-#define IP_TTL 2
-
-#if LWIP_TCP
-/*
- * Options for level IPPROTO_TCP
- */
-#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
-#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */
-#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */
-#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */
-#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */
-#endif /* LWIP_TCP */
-
-#if LWIP_UDP && LWIP_UDPLITE
-/*
- * Options for level IPPROTO_UDPLITE
- */
-#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
-#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
-#endif /* LWIP_UDP && LWIP_UDPLITE*/
-
-
-#if LWIP_IGMP
-/*
- * Options and types for UDP multicast traffic handling
- */
-#define IP_ADD_MEMBERSHIP 3
-#define IP_DROP_MEMBERSHIP 4
-#define IP_MULTICAST_TTL 5
-#define IP_MULTICAST_IF 6
-#define IP_MULTICAST_LOOP 7
-
-typedef struct ip_mreq {
- struct in_addr imr_multiaddr; /* IP multicast address of group */
- struct in_addr imr_interface; /* local IP address of interface */
-} ip_mreq;
-#endif /* LWIP_IGMP */
-
-/* Unimplemented for now... */
-#define IPTOS_TOS_MASK 0x1E
-#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK)
-#define IPTOS_LOWDELAY 0x10
-#define IPTOS_THROUGHPUT 0x08
-#define IPTOS_RELIABILITY 0x04
-#define IPTOS_LOWCOST 0x02
-#define IPTOS_MINCOST IPTOS_LOWCOST
-
-/*
- * Definitions for IP precedence (also in ip_tos) (Unimplemented)
- */
-#define IPTOS_PREC_MASK 0xe0
-#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK)
-#define IPTOS_PREC_NETCONTROL 0xe0
-#define IPTOS_PREC_INTERNETCONTROL 0xc0
-#define IPTOS_PREC_CRITIC_ECP 0xa0
-#define IPTOS_PREC_FLASHOVERRIDE 0x80
-#define IPTOS_PREC_FLASH 0x60
-#define IPTOS_PREC_IMMEDIATE 0x40
-#define IPTOS_PREC_PRIORITY 0x20
-#define IPTOS_PREC_ROUTINE 0x00
-
-
-/*
- * Commands for ioctlsocket(), taken from the BSD file fcntl.h.
- * lwip_ioctl only supports FIONREAD and FIONBIO, for now
- *
- * Ioctl's have the command encoded in the lower word,
- * and the size of any in or out parameters in the upper
- * word. The high 2 bits of the upper word are used
- * to encode the in/out status of the parameter; for now
- * we restrict parameters to at most 128 bytes.
- */
-#if !defined(FIONREAD) || !defined(FIONBIO)
-#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */
-#define IOC_VOID 0x20000000UL /* no parameters */
-#define IOC_OUT 0x40000000UL /* copy out parameters */
-#define IOC_IN 0x80000000UL /* copy in parameters */
-#define IOC_INOUT (IOC_IN|IOC_OUT)
- /* 0x20000000 distinguishes new &
- old ioctl's */
-#define _IO(x,y) (IOC_VOID|((x)<<8)|(y))
-
-#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
-
-#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
-#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
-
-#ifndef FIONREAD
-#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */
-#endif
-#ifndef FIONBIO
-#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */
-#endif
-
-/* Socket I/O Controls: unimplemented */
-#ifndef SIOCSHIWAT
-#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */
-#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */
-#define SIOCSLOWAT _IOW('s', 2, unsigned long) /* set low watermark */
-#define SIOCGLOWAT _IOR('s', 3, unsigned long) /* get low watermark */
-#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */
-#endif
-
-/* Socket flags: */
-#ifndef O_NONBLOCK
-#define O_NONBLOCK 04000U
-#endif
-
-/* FD_SET used for lwip_select */
-#ifndef FD_SET
- #undef FD_SETSIZE
- /* Make FD_SETSIZE match NUM_SOCKETS in socket.c */
- #define FD_SETSIZE MEMP_NUM_NETCONN
- #define FD_SET(n, p) ((p)->fd_bits[(n)/8] |= (1 << ((n) & 7)))
- #define FD_CLR(n, p) ((p)->fd_bits[(n)/8] &= ~(1 << ((n) & 7)))
- #define FD_ISSET(n,p) ((p)->fd_bits[(n)/8] & (1 << ((n) & 7)))
- #define FD_ZERO(p) memset((void*)(p),0,sizeof(*(p)))
-
- typedef struct fd_set {
- unsigned char fd_bits [(FD_SETSIZE+7)/8];
- } fd_set;
-
-#endif /* FD_SET */
-
-/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
- * by your system, set this to 0 and include <sys/time.h> in cc.h */
-#ifndef LWIP_TIMEVAL_PRIVATE
-#define LWIP_TIMEVAL_PRIVATE 1
-#endif
-
-#if LWIP_TIMEVAL_PRIVATE
-struct timeval {
- long tv_sec; /* seconds */
- long tv_usec; /* and microseconds */
-};
-#endif /* LWIP_TIMEVAL_PRIVATE */
-
-void lwip_socket_init(void);
-
-int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
-int lwip_bind(int s, struct sockaddr *name, socklen_t namelen);
-int lwip_shutdown(int s, int how);
-int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen);
-int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen);
-int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
-int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);
-int lwip_close(int s);
-int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen);
-int lwip_listen(int s, int backlog);
-int lwip_recv(int s, void *mem, int len, unsigned int flags);
-int lwip_read(int s, void *mem, int len);
-int lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
- struct sockaddr *from, socklen_t *fromlen);
-int lwip_send(int s, const void *dataptr, int size, unsigned int flags);
-int lwip_sendto(int s, const void *dataptr, int size, unsigned int flags,
- struct sockaddr *to, socklen_t tolen);
-int lwip_socket(int domain, int type, int protocol);
-int lwip_write(int s, const void *dataptr, int size);
-int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
- struct timeval *timeout);
-int lwip_ioctl(int s, long cmd, void *argp);
-
-#if LWIP_COMPAT_SOCKETS
-#define accept(a,b,c) lwip_accept(a,b,c)
-#define bind(a,b,c) lwip_bind(a,b,c)
-#define shutdown(a,b) lwip_shutdown(a,b)
-#define closesocket(s) lwip_close(s)
-#define connect(a,b,c) lwip_connect(a,b,c)
-#define getsockname(a,b,c) lwip_getsockname(a,b,c)
-#define getpeername(a,b,c) lwip_getpeername(a,b,c)
-#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e)
-#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e)
-#define listen(a,b) lwip_listen(a,b)
-#define recv(a,b,c,d) lwip_recv(a,b,c,d)
-#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f)
-#define send(a,b,c,d) lwip_send(a,b,c,d)
-#define sendto(a,b,c,d,e,f) lwip_sendto(a,b,c,d,e,f)
-#define socket(a,b,c) lwip_socket(a,b,c)
-#define select(a,b,c,d,e) lwip_select(a,b,c,d,e)
-#define ioctlsocket(a,b,c) lwip_ioctl(a,b,c)
-
-#if LWIP_POSIX_SOCKETS_IO_NAMES
-#define read(a,b,c) lwip_read(a,b,c)
-#define write(a,b,c) lwip_write(a,b,c)
-#define close(s) lwip_close(s)
-#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
-
-#endif /* LWIP_COMPAT_SOCKETS */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_SOCKET */
-
-#endif /* __LWIP_SOCKETS_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
#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
struct shadow_map;
struct vmm_io_map;
struct emulation_state;
+struct v3_intr_state;
-/*Zheng 07/30/2008*/
struct vm_ctrl_ops {
int (*raise_irq)(struct guest_info * info, int irq);
int (*lower_irq)(struct guest_info * info, int irq);
// This structure is how we get interrupts for the guest
- struct vm_intr intr_state;
+ struct v3_intr_state intr_state;
struct vmm_io_map io_map;
// device_map
void PrintV3CtrlRegs(struct guest_info * info);
void PrintV3GPRs(struct guest_info * info);
-#endif
+#endif // ! __V3VEE__
#ifndef __VM_GUEST_MEM_H
#define __VM_GUEST_MEM_H
+
+#ifdef __V3VEE__
+
#include <palacios/vm_guest.h>
#include <palacios/vmm_mem.h>
-int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, char * dest);
-int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * dest);
-int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * src);
+int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, uchar_t * dest);
+int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * dest);
+int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * src);
// TODO int write_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, char * src);
-
+#endif // ! __V3VEE__
#endif
struct Ctrl_Registers {
- uint_t cr0 : 1 PACKED;
- uint_t cr1 : 1 PACKED;
- uint_t cr2 : 1 PACKED;
- uint_t cr3 : 1 PACKED;
- uint_t cr4 : 1 PACKED;
- uint_t cr5 : 1 PACKED;
- uint_t cr6 : 1 PACKED;
- uint_t cr7 : 1 PACKED;
- uint_t cr8 : 1 PACKED;
- uint_t cr9 : 1 PACKED;
- uint_t cr10 : 1 PACKED;
- uint_t cr11 : 1 PACKED;
- uint_t cr12 : 1 PACKED;
- uint_t cr13 : 1 PACKED;
- uint_t cr14 : 1 PACKED;
- uint_t cr15 : 1 PACKED;
-};
+ uint_t cr0 : 1;
+ uint_t cr1 : 1;
+ uint_t cr2 : 1;
+ uint_t cr3 : 1;
+ uint_t cr4 : 1;
+ uint_t cr5 : 1;
+ uint_t cr6 : 1;
+ uint_t cr7 : 1;
+ uint_t cr8 : 1;
+ uint_t cr9 : 1;
+ uint_t cr10 : 1;
+ uint_t cr11 : 1;
+ uint_t cr12 : 1;
+ uint_t cr13 : 1;
+ uint_t cr14 : 1;
+ uint_t cr15 : 1;
+} __attribute__((packed));
struct Debug_Registers {
- uint_t dr0 : 1 PACKED;
- uint_t dr1 : 1 PACKED;
- uint_t dr2 : 1 PACKED;
- uint_t dr3 : 1 PACKED;
- uint_t dr4 : 1 PACKED;
- uint_t dr5 : 1 PACKED;
- uint_t dr6 : 1 PACKED;
- uint_t dr7 : 1 PACKED;
- uint_t dr8 : 1 PACKED;
- uint_t dr9 : 1 PACKED;
- uint_t dr10 : 1 PACKED;
- uint_t dr11 : 1 PACKED;
- uint_t dr12 : 1 PACKED;
- uint_t dr13 : 1 PACKED;
- uint_t dr14 : 1 PACKED;
- uint_t dr15 : 1 PACKED;
-};
+ uint_t dr0 : 1;
+ uint_t dr1 : 1;
+ uint_t dr2 : 1;
+ uint_t dr3 : 1;
+ uint_t dr4 : 1;
+ uint_t dr5 : 1;
+ uint_t dr6 : 1;
+ uint_t dr7 : 1;
+ uint_t dr8 : 1;
+ uint_t dr9 : 1;
+ uint_t dr10 : 1;
+ uint_t dr11 : 1;
+ uint_t dr12 : 1;
+ uint_t dr13 : 1;
+ uint_t dr14 : 1;
+ uint_t dr15 : 1;
+} __attribute__((packed));
struct Exception_Vectors {
- uint_t de : 1 PACKED; // (0) divide by zero
- uint_t db : 1 PACKED; // (1) Debug
- uint_t nmi : 1 PACKED; // (2) Non-maskable interrupt
- uint_t bp : 1 PACKED; // (3) Breakpoint
- uint_t of : 1 PACKED; // (4) Overflow
- uint_t br : 1 PACKED; // (5) Bound-Range
- uint_t ud : 1 PACKED; // (6) Invalid-Opcode
- uint_t nm : 1 PACKED; // (7) Device-not-available
- uint_t df : 1 PACKED; // (8) Double Fault
- uint_t ex9 : 1 PACKED;
- uint_t ts : 1 PACKED; // (10) Invalid TSS
- uint_t np : 1 PACKED; // (11) Segment-not-present
- uint_t ss : 1 PACKED; // (12) Stack
- uint_t gp : 1 PACKED; // (13) General Protection Fault
- uint_t pf : 1 PACKED; // (14) Page fault
- uint_t ex15 : 1 PACKED;
- uint_t mf : 1 PACKED; // (15) Floating point exception
- uint_t ac : 1 PACKED; // (16) Alignment-check
- uint_t mc : 1 PACKED; // (17) Machine Check
- uint_t xf : 1 PACKED; // (18) SIMD floating-point
- uint_t ex20 : 1 PACKED;
- uint_t ex21 : 1 PACKED;
- uint_t ex22 : 1 PACKED;
- uint_t ex23 : 1 PACKED;
- uint_t ex24 : 1 PACKED;
- uint_t ex25 : 1 PACKED;
- uint_t ex26 : 1 PACKED;
- uint_t ex27 : 1 PACKED;
- uint_t ex28 : 1 PACKED;
- uint_t ex29 : 1 PACKED;
- uint_t sx : 1 PACKED; // (30) Security Exception
- uint_t ex31 : 1 PACKED;
-};
+ uint_t de : 1; // (0) divide by zero
+ uint_t db : 1; // (1) Debug
+ uint_t nmi : 1; // (2) Non-maskable interrupt
+ uint_t bp : 1; // (3) Breakpoint
+ uint_t of : 1; // (4) Overflow
+ uint_t br : 1; // (5) Bound-Range
+ uint_t ud : 1; // (6) Invalid-Opcode
+ uint_t nm : 1; // (7) Device-not-available
+ uint_t df : 1; // (8) Double Fault
+ uint_t ex9 : 1;
+ uint_t ts : 1; // (10) Invalid TSS
+ uint_t np : 1; // (11) Segment-not-present
+ uint_t ss : 1; // (12) Stack
+ uint_t gp : 1; // (13) General Protection Fault
+ uint_t pf : 1; // (14) Page fault
+ uint_t ex15 : 1;
+ uint_t mf : 1; // (15) Floating point exception
+ uint_t ac : 1; // (16) Alignment-check
+ uint_t mc : 1; // (17) Machine Check
+ uint_t xf : 1; // (18) SIMD floating-point
+ uint_t ex20 : 1;
+ uint_t ex21 : 1;
+ uint_t ex22 : 1;
+ uint_t ex23 : 1;
+ uint_t ex24 : 1;
+ uint_t ex25 : 1;
+ uint_t ex26 : 1;
+ uint_t ex27 : 1;
+ uint_t ex28 : 1;
+ uint_t ex29 : 1;
+ uint_t sx : 1; // (30) Security Exception
+ uint_t ex31 : 1;
+} __attribute__((packed));
struct Instr_Intercepts {
- uint_t INTR : 1 PACKED;
- uint_t NMI : 1 PACKED;
- uint_t SMI : 1 PACKED;
- uint_t INIT : 1 PACKED;
- uint_t VINTR : 1 PACKED;
- uint_t CR0 : 1 PACKED;
- uint_t RD_IDTR : 1 PACKED;
- uint_t RD_GDTR : 1 PACKED;
- uint_t RD_LDTR : 1 PACKED;
- uint_t RD_TR : 1 PACKED;
- uint_t WR_IDTR : 1 PACKED;
- uint_t WR_GDTR : 1 PACKED;
- uint_t WR_LDTR : 1 PACKED;
- uint_t WR_TR : 1 PACKED;
- uint_t RDTSC : 1 PACKED;
- uint_t RDPMC : 1 PACKED;
- uint_t PUSHF : 1 PACKED;
- uint_t POPF : 1 PACKED;
- uint_t CPUID : 1 PACKED;
- uint_t RSM : 1 PACKED;
- uint_t IRET : 1 PACKED;
- uint_t INTn : 1 PACKED;
- uint_t INVD : 1 PACKED;
- uint_t PAUSE : 1 PACKED;
- uint_t HLT : 1 PACKED;
- uint_t INVLPG : 1 PACKED;
- uint_t INVLPGA : 1 PACKED;
- uint_t IOIO_PROT : 1 PACKED;
- uint_t MSR_PROT : 1 PACKED;
- uint_t task_switch : 1 PACKED;
- uint_t FERR_FREEZE : 1 PACKED;
- uint_t shutdown_evts: 1 PACKED;
-};
+ uint_t INTR : 1;
+ uint_t NMI : 1;
+ uint_t SMI : 1;
+ uint_t INIT : 1;
+ uint_t VINTR : 1;
+ uint_t CR0 : 1;
+ uint_t RD_IDTR : 1;
+ uint_t RD_GDTR : 1;
+ uint_t RD_LDTR : 1;
+ uint_t RD_TR : 1;
+ uint_t WR_IDTR : 1;
+ uint_t WR_GDTR : 1;
+ uint_t WR_LDTR : 1;
+ uint_t WR_TR : 1;
+ uint_t RDTSC : 1;
+ uint_t RDPMC : 1;
+ uint_t PUSHF : 1;
+ uint_t POPF : 1;
+ uint_t CPUID : 1;
+ uint_t RSM : 1;
+ uint_t IRET : 1;
+ uint_t INTn : 1;
+ uint_t INVD : 1;
+ uint_t PAUSE : 1;
+ uint_t HLT : 1;
+ uint_t INVLPG : 1;
+ uint_t INVLPGA : 1;
+ uint_t IOIO_PROT : 1;
+ uint_t MSR_PROT : 1;
+ uint_t task_switch : 1;
+ uint_t FERR_FREEZE : 1;
+ uint_t shutdown_evts: 1;
+} __attribute__((packed));
struct SVM_Instr_Intercepts {
- uint_t VMRUN : 1 PACKED;
- uint_t VMMCALL : 1 PACKED;
- uint_t VMLOAD : 1 PACKED;
- uint_t VMSAVE : 1 PACKED;
- uint_t STGI : 1 PACKED;
- uint_t CLGI : 1 PACKED;
- uint_t SKINIT : 1 PACKED;
- uint_t RDTSCP : 1 PACKED;
- uint_t ICEBP : 1 PACKED;
- uint_t WBINVD : 1 PACKED;
- uint_t MONITOR : 1 PACKED;
- uint_t MWAIT_always : 1 PACKED;
- uint_t MWAIT_if_armed : 1 PACKED;
- uint_t reserved : 19 PACKED; // Should be 0
-};
+ uint_t VMRUN : 1;
+ uint_t VMMCALL : 1;
+ uint_t VMLOAD : 1;
+ uint_t VMSAVE : 1;
+ uint_t STGI : 1;
+ uint_t CLGI : 1;
+ uint_t SKINIT : 1;
+ uint_t RDTSCP : 1;
+ uint_t ICEBP : 1;
+ uint_t WBINVD : 1;
+ uint_t MONITOR : 1;
+ uint_t MWAIT_always : 1;
+ uint_t MWAIT_if_armed : 1;
+ uint_t reserved : 19; // Should be 0
+} __attribute__((packed));
struct Guest_Control {
- uchar_t V_TPR PACKED;
- uint_t V_IRQ : 1 PACKED;
- uint_t rsvd1 : 7 PACKED; // Should be 0
- uint_t V_INTR_PRIO : 4 PACKED;
- uint_t V_IGN_TPR : 1 PACKED;
- uint_t rsvd2 : 3 PACKED; // Should be 0
- uint_t V_INTR_MASKING : 1 PACKED;
- uint_t rsvd3 : 7 PACKED; // Should be 0
- uchar_t V_INTR_VECTOR PACKED;
- uint_t rsvd4 : 24 PACKED; // Should be 0
-};
+ uchar_t V_TPR;
+ uint_t V_IRQ : 1;
+ uint_t rsvd1 : 7; // Should be 0
+ uint_t V_INTR_PRIO : 4;
+ uint_t V_IGN_TPR : 1;
+ uint_t rsvd2 : 3; // Should be 0
+ uint_t V_INTR_MASKING : 1;
+ uint_t rsvd3 : 7; // Should be 0
+ uchar_t V_INTR_VECTOR;
+ uint_t rsvd4 : 24; // Should be 0
+} __attribute__((packed));
#define SVM_INJECTION_EXTERNAL_INTR 0
#define SVM_INJECTION_VIRTUAL_INTR 0
#define SVM_INJECTION_SOFT_INTR 4
struct Interrupt_Info {
- uint_t vector : 8 PACKED;
- uint_t type : 3 PACKED;
- uint_t ev : 1 PACKED;
- uint_t rsvd : 19 PACKED;
- uint_t valid : 1 PACKED;
- uint_t error_code : 32 PACKED;
-};
+ uint_t vector : 8;
+ uint_t type : 3;
+ uint_t ev : 1;
+ uint_t rsvd : 19;
+ uint_t valid : 1;
+ uint_t error_code : 32;
+} __attribute__((packed));
-typedef struct VMCB_Control_Area {
+
+struct VMCB_Control_Area {
// offset 0x0
- struct Ctrl_Registers cr_reads PACKED;
- struct Ctrl_Registers cr_writes PACKED;
- struct Debug_Registers dr_reads PACKED;
- struct Debug_Registers dr_writes PACKED;
- struct Exception_Vectors exceptions PACKED;
- struct Instr_Intercepts instrs PACKED;
- struct SVM_Instr_Intercepts svm_instrs PACKED;
+ struct Ctrl_Registers cr_reads;
+ struct Ctrl_Registers cr_writes;
+ struct Debug_Registers dr_reads;
+ struct Debug_Registers dr_writes;
+ struct Exception_Vectors exceptions;
+ struct Instr_Intercepts instrs;
+ struct SVM_Instr_Intercepts svm_instrs;
- uchar_t rsvd1[44] PACKED; // Should be 0
+ uchar_t rsvd1[44]; // Should be 0
// offset 0x040
- ullong_t IOPM_BASE_PA PACKED;
- ullong_t MSRPM_BASE_PA PACKED;
- ullong_t TSC_OFFSET PACKED;
+ ullong_t IOPM_BASE_PA;
+ ullong_t MSRPM_BASE_PA;
+ ullong_t TSC_OFFSET;
- uint_t guest_ASID PACKED;
- uchar_t TLB_CONTROL PACKED;
+ uint_t guest_ASID;
+ uchar_t TLB_CONTROL;
- uchar_t rsvd2[3] PACKED; // Should be 0
+ uchar_t rsvd2[3]; // Should be 0
- struct Guest_Control guest_ctrl PACKED;
+ struct Guest_Control guest_ctrl;
- uint_t interrupt_shadow : 1 PACKED;
- uint_t rsvd3 : 31 PACKED; // Should be 0
- uint_t rsvd4 PACKED; // Should be 0
+ uint_t interrupt_shadow : 1;
+ uint_t rsvd3 : 31; // Should be 0
+ uint_t rsvd4; // Should be 0
- ullong_t exit_code PACKED;
- ullong_t exit_info1 PACKED;
- ullong_t exit_info2 PACKED;
+ ullong_t exit_code;
+ ullong_t exit_info1;
+ ullong_t exit_info2;
/* This could be a typo in the manual....
* It doesn't actually say that there is a reserved bit
* But it does say that the EXITINTINFO field is in bits 63-1
* ALL other occurances mention a 1 bit reserved field
*/
- // uint_t rsvd5 : 1 PACKED;
- //ullong_t exit_int_info : 63 PACKED;
+ // uint_t rsvd5 : 1;
+ //ullong_t exit_int_info : 63;
/* ** */
// AMD Manual 2, pg 391, sect: 15.19
- struct Interrupt_Info exit_int_info PACKED;
+ struct Interrupt_Info exit_int_info;
- // uint_t NP_ENABLE : 1 PACKED;
- //ullong_t rsvd6 : 63 PACKED; // Should be 0
- ullong_t NP_ENABLE PACKED;
+ // uint_t NP_ENABLE : 1;
+ //ullong_t rsvd6 : 63; // Should be 0
+ ullong_t NP_ENABLE;
- uchar_t rsvd7[16] PACKED; // Should be 0
+ uchar_t rsvd7[16]; // Should be 0
// Offset 0xA8
- struct Interrupt_Info EVENTINJ PACKED;
+ struct Interrupt_Info EVENTINJ;
/* This could be a typo in the manual....
* But it does say that the EXITINTINFO field is in bits 63-1
* ALL other occurances mention a 1 bit reserved field
*/
- // uint_t rsvd8 : 1 PACKED;
- //ullong_t N_CR3 : 63 PACKED;
- ullong_t N_CR3 PACKED;
+ // uint_t rsvd8 : 1;
+ //ullong_t N_CR3 : 63;
+ ullong_t N_CR3;
/* ** */
- uint_t LBR_VIRTUALIZATION_ENABLE : 1 PACKED;
- ullong_t rsvd9 : 63 PACKED; // Should be 0
+ uint_t LBR_VIRTUALIZATION_ENABLE : 1;
+ ullong_t rsvd9 : 63; // Should be 0
+
+} __attribute__((packed));
+
-} vmcb_ctrl_t;
+typedef struct VMCB_Control_Area vmcb_ctrl_t;
struct vmcb_selector {
- ushort_t selector PACKED;
+ ushort_t selector;
/* These attributes are basically a direct map of the attribute fields of a segment desc.
* The segment limit in the middle is removed and the fields are fused together
* There IS empty space at the end... See AMD Arch vol3, sect. 4.7.1, pg 78
*/
union {
- ushort_t raw PACKED;
+ ushort_t raw;
struct {
- uint_t type : 4 PACKED; // segment type, [see Intel vol. 3b, sect. 3.4.5.1 (because I have the books)]
- uint_t S : 1 PACKED; // System=0, code/data=1
- uint_t dpl : 2 PACKED; // priviledge level, corresonds to protection ring
- uint_t P : 1 PACKED; // present flag
- uint_t avl : 1 PACKED; // available for use by system software
- uint_t L : 1 PACKED; // long mode (64 bit?)
- uint_t db : 1 PACKED; // default op size (0=16 bit seg, 1=32 bit seg)
- uint_t G : 1 PACKED; // Granularity, (0=bytes, 1=4k)
- uint_t rsvd : 4 PACKED;
- } fields;
- } attrib;
- uint_t limit PACKED;
- ullong_t base PACKED;
-};
-
-
-typedef struct VMCB_State_Save_Area {
- struct vmcb_selector es PACKED; // only lower 32 bits of base are implemented
- struct vmcb_selector cs PACKED; // only lower 32 bits of base are implemented
- struct vmcb_selector ss PACKED; // only lower 32 bits of base are implemented
- struct vmcb_selector ds PACKED; // only lower 32 bits of base are implemented
- struct vmcb_selector fs PACKED;
- struct vmcb_selector gs PACKED;
-
- struct vmcb_selector gdtr PACKED; // selector+attrib are reserved, only lower 16 bits of limit are implemented
- struct vmcb_selector ldtr PACKED;
- struct vmcb_selector idtr PACKED; // selector+attrib are reserved, only lower 16 bits of limit are implemented
- struct vmcb_selector tr PACKED;
-
- uchar_t rsvd1[43] PACKED;
+ uint_t type : 4; // segment type, [see Intel vol. 3b, sect. 3.4.5.1 (because I have the books)]
+ uint_t S : 1; // System=0, code/data=1
+ uint_t dpl : 2; // priviledge level, corresonds to protection ring
+ uint_t P : 1; // present flag
+ uint_t avl : 1; // available for use by system software
+ uint_t L : 1; // long mode (64 bit?)
+ uint_t db : 1; // default op size (0=16 bit seg, 1=32 bit seg)
+ uint_t G : 1; // Granularity, (0=bytes, 1=4k)
+ uint_t rsvd : 4;
+ } __attribute__((packed)) fields;
+ } __attribute__((packed)) attrib;
+
+ uint_t limit;
+ ullong_t base;
+} __attribute__((packed));
+
+
+struct VMCB_State_Save_Area {
+ struct vmcb_selector es; // only lower 32 bits of base are implemented
+ struct vmcb_selector cs; // only lower 32 bits of base are implemented
+ struct vmcb_selector ss; // only lower 32 bits of base are implemented
+ struct vmcb_selector ds; // only lower 32 bits of base are implemented
+ struct vmcb_selector fs;
+ struct vmcb_selector gs;
+
+ struct vmcb_selector gdtr; // selector+attrib are reserved, only lower 16 bits of limit are implemented
+ struct vmcb_selector ldtr;
+ struct vmcb_selector idtr; // selector+attrib are reserved, only lower 16 bits of limit are implemented
+ struct vmcb_selector tr;
+
+ uchar_t rsvd1[43];
//offset 0x0cb
- uchar_t cpl PACKED; // if the guest is real-mode then the CPL is forced to 0
+ uchar_t cpl; // if the guest is real-mode then the CPL is forced to 0
// if the guest is virtual-mode then the CPL is forced to 3
- uint_t rsvd2 PACKED;
+ uint_t rsvd2;
// offset 0x0d0
- ullong_t efer PACKED;
+ ullong_t efer;
- uchar_t rsvd3[112] PACKED;
+ uchar_t rsvd3[112];
//offset 0x148
- ullong_t cr4 PACKED;
- ullong_t cr3 PACKED;
- ullong_t cr0 PACKED;
- ullong_t dr7 PACKED;
- ullong_t dr6 PACKED;
- ullong_t rflags PACKED;
- ullong_t rip PACKED;
-
- uchar_t rsvd4[88] PACKED;
+ ullong_t cr4;
+ ullong_t cr3;
+ ullong_t cr0;
+ ullong_t dr7;
+ ullong_t dr6;
+ ullong_t rflags;
+ ullong_t rip;
+
+ uchar_t rsvd4[88];
//offset 0x1d8
- ullong_t rsp PACKED;
+ ullong_t rsp;
- uchar_t rsvd5[24] PACKED;
+ uchar_t rsvd5[24];
//offset 0x1f8
- ullong_t rax PACKED;
- ullong_t star PACKED;
- ullong_t lstar PACKED;
- ullong_t cstar PACKED;
- ullong_t sfmask PACKED;
- ullong_t KernelGsBase PACKED;
- ullong_t sysenter_cs PACKED;
- ullong_t sysenter_esp PACKED;
- ullong_t sysenter_eip PACKED;
- ullong_t cr2 PACKED;
+ ullong_t rax;
+ ullong_t star;
+ ullong_t lstar;
+ ullong_t cstar;
+ ullong_t sfmask;
+ ullong_t KernelGsBase;
+ ullong_t sysenter_cs;
+ ullong_t sysenter_esp;
+ ullong_t sysenter_eip;
+ ullong_t cr2;
- uchar_t rsvd6[32] PACKED;
+ uchar_t rsvd6[32];
//offset 0x268
- ullong_t g_pat PACKED; // Guest PAT
+ ullong_t g_pat; // Guest PAT
// -- only used if nested paging is enabled
- ullong_t dbgctl PACKED; // Guest DBGCTL MSR
+ ullong_t dbgctl; // Guest DBGCTL MSR
// -- only used if the LBR registers are virtualized
- ullong_t br_from PACKED; // Guest LastBranchFromIP MSR
+ ullong_t br_from; // Guest LastBranchFromIP MSR
// -- only used if the LBR registers are virtualized
- ullong_t br_to PACKED; // Guest LastBranchToIP MSR
+ ullong_t br_to; // Guest LastBranchToIP MSR
// -- only used if the LBR registers are virtualized
- ullong_t lastexcpfrom PACKED; // Guest LastExceptionFromIP MSR
+ ullong_t lastexcpfrom; // Guest LastExceptionFromIP MSR
// -- only used if the LBR registers are virtualized
- ullong_t lastexcpto PACKED; // Guest LastExceptionToIP MSR
+ ullong_t lastexcpto; // Guest LastExceptionToIP MSR
// -- only used if the LBR registers are virtualized
-} vmcb_saved_state_t;
+} __attribute__((packed));
+
+
+typedef struct VMCB_State_Save_Area vmcb_saved_state_t;
void PrintDebugVMCB(vmcb_t * vmcb);
* redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
-#ifndef __VMCS_H
-#define __VMCS_H
+
+
+#ifndef __VMCS_H__
+#define __VMCS_H__
+
+#ifdef __V3VEE__
+
+
#include <palacios/vmm_types.h>
typedef void VMCS;
-#if __TINYC__
-#define PACKED
-#else
-#define PACKED __attribute__((packed))
-#endif
-
/* VMCS Exit QUALIFICATIONs */
struct VMExitIOQual {
- uint_t accessSize : 3 PACKED; // (0: 1 Byte ;; 1: 2 Bytes ;; 3: 4 Bytes)
- uint_t dir : 1 PACKED; // (0: Out ;; 1: In)
- uint_t string : 1 PACKED; // (0: not string ;; 1: string)
- uint_t REP : 1 PACKED; // (0: not REP ;; 1: REP)
- uint_t opEnc : 1 PACKED; // (0: DX ;; 1: immediate)
- uint_t rsvd : 9 PACKED; // Set to 0
- uint_t port : 16 PACKED; // IO Port Number
-};
+ uint_t accessSize : 3; // (0: 1 Byte ;; 1: 2 Bytes ;; 3: 4 Bytes)
+ uint_t dir : 1; // (0: Out ;; 1: In)
+ uint_t string : 1; // (0: not string ;; 1: string)
+ uint_t REP : 1; // (0: not REP ;; 1: REP)
+ uint_t opEnc : 1; // (0: DX ;; 1: immediate)
+ uint_t rsvd : 9; // Set to 0
+ uint_t port : 16; // IO Port Number
+} __attribute__((packed));
struct VMExitDBGQual {
- uint_t B0 : 1 PACKED; // Breakpoint 0 condition met
- uint_t B1 : 1 PACKED; // Breakpoint 1 condition met
- uint_t B2 : 1 PACKED; // Breakpoint 2 condition met
- uint_t B3 : 1 PACKED; // Breakpoint 3 condition met
- uint_t rsvd : 9 PACKED; // reserved to 0
- uint_t BD : 1 PACKED; // detected DBG reg access
- uint_t BS : 1 PACKED; // cause either single instr or taken branch
-};
+ uint_t B0 : 1; // Breakpoint 0 condition met
+ uint_t B1 : 1; // Breakpoint 1 condition met
+ uint_t B2 : 1; // Breakpoint 2 condition met
+ uint_t B3 : 1; // Breakpoint 3 condition met
+ uint_t rsvd : 9; // reserved to 0
+ uint_t BD : 1; // detected DBG reg access
+ uint_t BS : 1; // cause either single instr or taken branch
+} __attribute__((packed));
struct VMExitTSQual {
- uint_t selector : 16 PACKED; // selector of destination TSS
- uint_t rsvd : 14 PACKED; // reserved to 0
- uint_t src : 2 PACKED; // (0: CALL ; 1: IRET ; 2: JMP ; 3: Task gate in IDT)
-};
+ uint_t selector : 16; // selector of destination TSS
+ uint_t rsvd : 14; // reserved to 0
+ uint_t src : 2; // (0: CALL ; 1: IRET ; 2: JMP ; 3: Task gate in IDT)
+} __attribute__((packed));
struct VMExitCRQual {
- uint_t crID : 4 PACKED; // cr number (0 for CLTS and LMSW) (bit 3 always 0, on 32bit)
- uint_t accessType : 2 PACKED; // (0: MOV to CR ; 1: MOV from CR ; 2: CLTS ; 3: LMSW)
- uint_t lmswOpType : 1 PACKED; // (0: register ; 1: memory)
- uint_t rsvd1 : 1 PACKED; // reserved to 0
- uint_t gpr : 4 PACKED; // (0:RAX+[CLTS/LMSW], 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
- uint_t rsvd2 : 4 PACKED; // reserved to 0
- uint_t lmswSrc : 16 PACKED; // src data for lmsw
-};
+ uint_t crID : 4; // cr number (0 for CLTS and LMSW) (bit 3 always 0, on 32bit)
+ uint_t accessType : 2; // (0: MOV to CR ; 1: MOV from CR ; 2: CLTS ; 3: LMSW)
+ uint_t lmswOpType : 1; // (0: register ; 1: memory)
+ uint_t rsvd1 : 1; // reserved to 0
+ uint_t gpr : 4; // (0:RAX+[CLTS/LMSW], 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
+ uint_t rsvd2 : 4; // reserved to 0
+ uint_t lmswSrc : 16; // src data for lmsw
+} __attribute__((packed));
struct VMExitMovDRQual {
- uint_t regID : 3 PACKED; // debug register number
- uint_t rsvd1 : 1 PACKED; // reserved to 0
- uint_t dir : 1 PACKED; // (0: MOV to DR , 1: MOV from DR)
- uint_t rsvd2 : 3 PACKED; // reserved to 0
- uint_t gpr : 4 PACKED; // (0:RAX, 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
-};
+ uint_t regID : 3; // debug register number
+ uint_t rsvd1 : 1; // reserved to 0
+ uint_t dir : 1; // (0: MOV to DR , 1: MOV from DR)
+ uint_t rsvd2 : 3; // reserved to 0
+ uint_t gpr : 4; // (0:RAX, 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
+} __attribute__((packed));
/* End Exit Qualifications */
/* Exit Vector Info */
struct VMExitIntInfo {
- uint_t nr : 8 PACKED; // IRQ number, exception vector, NMI = 2
- uint_t type : 3 PACKED; // (0: ext. IRQ , 2: NMI , 3: hw exception , 6: sw exception
- uint_t errorCode : 1 PACKED; // 1: error Code present
- uint_t iret : 1 PACKED; // something to do with NMIs and IRETs (Intel 3B, sec. 23.2.2)
- uint_t rsvd : 18 PACKED; // always 0
- uint_t valid : 1 PACKED; // always 1 if valid
-};
+ uint_t nr : 8; // IRQ number, exception vector, NMI = 2
+ uint_t type : 3; // (0: ext. IRQ , 2: NMI , 3: hw exception , 6: sw exception
+ uint_t errorCode : 1; // 1: error Code present
+ uint_t iret : 1; // something to do with NMIs and IRETs (Intel 3B, sec. 23.2.2)
+ uint_t rsvd : 18; // always 0
+ uint_t valid : 1; // always 1 if valid
+} __attribute__((packed));
/* INTEL Manual: 20-4 vol 3B */
union SegAccess {
struct {
- uchar_t type PACKED;
- uint_t descType : 1 PACKED;
- uint_t dpl : 2 PACKED;
- uint_t present : 1 PACKED;
- uchar_t rsvd1 PACKED;
- uint_t avail : 1 PACKED ;
- uint_t L : 1 PACKED ; // CS only (64 bit active), reserved otherwise
- uint_t DB : 1 PACKED ;
- uint_t granularity : 1 PACKED ;
- uint_t unusable : 1 PACKED ;
- uint_t rsvd2 : 15 PACKED ;
- } as_fields;
+ uchar_t type;
+ uint_t descType : 1;
+ uint_t dpl : 2;
+ uint_t present : 1;
+ uchar_t rsvd1;
+ uint_t avail : 1;
+ uint_t L : 1; // CS only (64 bit active), reserved otherwise
+ uint_t DB : 1;
+ uint_t granularity : 1;
+ uint_t unusable : 1;
+ uint_t rsvd2 : 15;
+ } __attribute__((packed)) as_fields;
uint_t as_dword;
-};
+} __attribute__((packed));
struct VMCSSegment {
};
-int CopyOutVMCSGuestStateArea(struct VMCSGuestStateArea *p);
-int CopyInVMCSGuestStateArea(struct VMCSGuestStateArea *p);
+int CopyOutVMCSGuestStateArea(struct VMCSGuestStateArea * p);
+int CopyInVMCSGuestStateArea(struct VMCSGuestStateArea * p);
#include <palacios/vmcs_gen.h>
+#endif // ! __V3VEE__
+
+
#endif
-
/*
* This file is part of the Palacios Virtual Machine Monitor developed
* by the V3VEE Project with funding from the United States National
#ifdef __V3VEE__
-
#include <palacios/vmcs.h>
#include <palacios/vmm.h>
void PrintTrace_HOST_RIP();
void PrintTrace_VMCS_ALL();
-#endif
+
+
+#endif // !__V3VEE
#endif
+
+
-#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 interrupt state that the VMM's interrupt handlers need to see
-//
-struct vmm_intr_state {
- unsigned int irq;
- unsigned int error;
-
- unsigned int should_ack; // Should the vmm ack this interrupt, or will
- // the host OS do it?
-
- // This is the value given when the interrupt is hooked.
- // This will never be NULL
- void *opaque;
-};
-
-void deliver_interrupt_to_vmm(struct vmm_intr_state *state);
-
+struct guest_info;
/* This will contain function pointers that provide OS services */
struct vmm_os_hooks {
// int (*hook_interrupt)(struct guest_info *s, int irq);
- int (*hook_interrupt)(unsigned int irq, void *opaque);
+ int (*hook_interrupt)(struct guest_info * vm, unsigned int irq);
int (*ack_irq)(int irq);
void (*start_kernel_thread)(); // include pointer to function
+ void (*yield_cpu)();
+
+};
+struct v3_vm_config {
+ void * vm_kernel;
+ int use_ramdisk;
+ void * ramdisk;
+ int ramdisk_size;
};
+
/* This will contain Function pointers that control the VMs */
struct vmm_ctrl_ops {
struct guest_info *(*allocate_guest)();
- int (*config_guest)(struct guest_info * info, void * config_ptr);
+ int (*config_guest)(struct guest_info * info, struct v3_vm_config * config_ptr);
int (*init_guest)(struct guest_info * info);
int (*start_guest)(struct guest_info * info);
// int (*stop_vm)(uint_t vm_id);
-void Init_V3(struct vmm_os_hooks * hooks, struct vmm_ctrl_ops * vmm_ops);
+//
+//
+// This is the interrupt state that the VMM's interrupt handlers need to see
+//
+struct v3_interrupt {
+ unsigned int irq;
+ unsigned int error;
+
+ unsigned int should_ack; // Should the vmm ack this interrupt, or will
+ // the host OS do it?
+};
+
+void Init_V3(struct vmm_os_hooks * hooks, struct vmm_ctrl_ops * vmm_ops);
+
+int v3_deliver_irq(struct guest_info * vm, struct v3_interrupt * intr);
+
#endif
#ifdef __V3VEE__
-#include <palacios/vm_guest.h>
-
-
-
-
-#define MAGIC_CODE 0xf1e2d3c4
-struct layout_region {
- ulong_t length;
- ulong_t final_addr;
-};
-
-struct guest_mem_layout {
- ulong_t magic;
- ulong_t num_regions;
- struct layout_region regions[0];
-};
-
-
-
-int config_guest(struct guest_info * info, void * config_ptr);
+#include <palacios/vm_guest.h>
+#include <palacios/vmm.h>
+int config_guest(struct guest_info * info, struct v3_vm_config * config_ptr);
#endif // ! __V3VEE__
#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
#ifdef __V3VEE__
+
#include <palacios/vmm.h>
struct dbg_bp32 {
-void PrintDebugHex(unsigned char x);
-void PrintDebugMemDump(unsigned char *start, int n);
+void PrintDebugHex(uchar_t x);
+void PrintDebugMemDump(uchar_t * start, int n);
int opcode_cmp(const uchar_t * op1, const uchar_t * op2);
-static inline int is_prefix_byte(char byte) {
+static inline int is_prefix_byte(uchar_t byte) {
switch (byte) {
case 0xF0: // lock
case 0xF2: // REPNE/REPNZ
static inline operand_type_t decode_operands32(struct v3_gprs * gprs, // input/output
- char * modrm_instr, // input
+ uchar_t * modrm_instr, // input
int * offset, // output
addr_t * first_operand, // output
addr_t * second_operand, // output
reg_size_t reg_size) { // input
- char * instr_cursor = modrm_instr;
+ uchar_t * instr_cursor = modrm_instr;
struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
addr_t base_addr = 0;
modrm_mode_t mod_mode = 0;
#include <palacios/vmm_intr.h>
#include <palacios/vmm_types.h>
+
#define DE_EXCEPTION 0x00
#define DB_EXCEPTION 0x01
#define NMI_EXCEPTION 0x02
typedef enum {INVALID_INTR, EXTERNAL_IRQ, NMI, EXCEPTION, SOFTWARE_INTR, VIRTUAL_INTR} intr_type_t;
struct guest_info;
+struct v3_interrupt;
/* We need a way to allow the APIC/PIC to decide when they are supposed to receive interrupts...
* Maybe a notification call when they have been turned on, to deliver irqs to them...
*/
-struct vm_intr {
+struct v3_irq_hook {
+ int (*handler)(struct guest_info * info, struct v3_interrupt * intr, void * priv_data);
+ void * priv_data;
+};
+
+
+struct v3_intr_state {
/* We need to rework the exception state, to handle stacking */
uint_t excp_pending;
/* some way to get the [A]PIC intr */
+ struct v3_irq_hook * hooks[256];
+
};
int end_irq(struct vm_intr * intr, int irq);
*/
-#endif // !__V3VEE__
-
-
+int v3_hook_irq(struct guest_info * info,
+ uint_t irq,
+ int (*handler)(struct guest_info * info, struct v3_interrupt * intr, void * priv_data),
+ void * priv_data);
+int v3_hook_passthrough_irq(struct guest_info *info, uint_t irq);
-struct vmm_intr_state;
-
-int v3_hook_irq(uint_t irq,
- void (*handler)(struct vmm_intr_state *state),
- void *opaque);
+#endif // !__V3VEE__
-int v3_hook_irq_for_guest_injection(struct guest_info *info, int irq);
#endif
#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__
#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
#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
--- /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 */
#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);
char *strpbrk(const char *s, const char *accept);
-double ceil(double x);
+double v3_ceil(double x);
+
#endif // !__V3VEE__
#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);
#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
#include <palacios/vmm_types.h>
-#ifndef PAGE_SIZE
-#define PAGE_SIZE 4096
-#endif
-
-
typedef union reg_ex {
ullong_t r_reg;
struct {
#define GET_LOW_32(x) (*((uint_t*)(&(x))))
-#define GET_HIGH_32(x) (*((uint_t*)(((char*)(&(x)))+4)))
+#define GET_HIGH_32(x) (*((uint_t*)(((uchar_t*)(&(x)))+4)))
-void PrintTraceHex(unsigned char x);
+void PrintTraceHex(uchar_t x);
void PrintTraceLL(ullong_t num);
-void PrintTraceMemDump(unsigned char * start, int n);
+void PrintTraceMemDump(uchar_t * start, int n);
#ifdef __V3_64BIT__
+#define do_divll do_div
+
-# define do_div(n,base) ({ \
+#define do_div(n,base) ({ \
uint32_t __base = (base); \
uint32_t __rem; \
__rem = ((uint64_t)(n)) % __base; \
#ifndef __VMX_H
#define __VMX_H
+#ifdef __V3VEE__
+
#include <palacios/vmm_types.h>
#include <palacios/vmcs.h>
typedef void VmxOnRegion;
-#if __TINYC__
-#define PACKED
-#else
-#define PACKED __attribute__((packed))
-#endif
struct MSR_REGS {
- uint_t low PACKED;
- uint_t high PACKED;
-};
+ uint_t low;
+ uint_t high;
+} __attribute__((packed));
struct VMX_BASIC {
- uint_t revision PACKED ;
- uint_t regionSize : 13 PACKED ;
- uint_t rsvd1 : 4 PACKED ; // Always 0
- uint_t physWidth : 1 PACKED ;
- uint_t smm : 1 PACKED ; // Always 1
- uint_t memType : 4 PACKED ;
- uint_t rsvd2 : 10 PACKED ; // Always 0
-};
+ uint_t revision;
+ uint_t regionSize : 13;
+ uint_t rsvd1 : 4; // Always 0
+ uint_t physWidth : 1;
+ uint_t smm : 1; // Always 1
+ uint_t memType : 4;
+ uint_t rsvd2 : 10; // Always 0
+} __attribute__((packed));
union VMX_MSR {
- struct MSR_REGS regs PACKED;
- struct VMX_BASIC vmxBasic PACKED;
-};
+ struct MSR_REGS regs;
+ struct VMX_BASIC vmxBasic;
+} __attribute__((packed));
struct VMDescriptor {
uint_t entry_ip;
uint_t exit_eip;
uint_t guest_esp;
-} ;
+} __attribute__((packed));
enum VMState { VM_VMXASSIST_STARTUP, VM_VMXASSIST_V8086_BIOS, VM_VMXASSIST_V8086, VM_NORMAL };
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;
/*
-
* 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.
* redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
+
#include <devices/cdrom.h>
+#include <devices/ide.h>
#include <palacios/vmm.h>
-#ifdef DEBUG_RAMDISK
-#define Ramdisk_Print_CD(_f, _a...) PrintTrace("cdrom.c(%d) "_f, __LINE__, ## _a)
-#else
-#define Ramdisk_Print_CD(_f, _a...)
+#ifndef DEBUG_RAMDISK
+#undef PrintDebug
+#define PrintDebug(fmt, args...)
#endif
-extern ulong_t g_ramdiskImage;
-extern ulong_t s_ramdiskSize;
-static
-void cdrom_init(struct cdrom_interface * cdrom)
-{
+struct cdrom_state {
+ uchar_t * image_addr; //memory address
+ ulong_t capacity_in_bytes;
+ ulong_t head; //current position
+
+ struct vm_device * ide_dev;
+
+ uchar_t lba;
+};
+
+
- Ramdisk_Print_CD("[cdrom_init]\n");
- V3_ASSERT(g_ramdiskImage);
- cdrom->fd = g_ramdiskImage;
- cdrom->capacity_B = s_ramdiskSize;
- //FIXME:lba
- cdrom->lba = 1;
- return;
-}
/*
* Load CD-ROM. Returns false if CD is not ready.
*/
-static
-rd_bool cdrom_insert(struct cdrom_interface * cdrom, char *dev /*= NULL*/)
-{
- Ramdisk_Print_CD("[cdrom_insert]\n");
+static rd_bool cdrom_insert(void * private_data) {
+ PrintDebug("[cdrom_insert]\n");
return 1;
}
/*
* Logically eject the CD.
*/
-static
-void cdrom_eject(struct cdrom_interface *cdrom)
-{
- Ramdisk_Print_CD("[cdrom_eject]\n");
+static void cdrom_eject(void * private_data) {
+ PrintDebug("[cdrom_eject]\n");
return;
}
/*
* 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)
+static rd_bool cdrom_read_toc(void * private_data, uint8_t* buf, int* length, rd_bool msf, int start_track)
{
- Ramdisk_Print_CD("[cdrom_read_toc]\n");
+ PrintDebug("[cdrom_read_toc]\n");
return 1;
}
/*
* Return CD-ROM capacity (in 2048 byte frames)
*/
-static
-uint32 cdrom_capacity(struct cdrom_interface *cdrom)
-{
- Ramdisk_Print_CD("[cdrom_capacity] s_ramdiskSize = %d\n", cdrom->capacity_B);
+static uint32_t cdrom_capacity(void * private_data) {
+ struct cdrom_state * cdrom = (struct cdrom_state *)private_data;
+
+ PrintDebug("[cdrom_capacity] s_ramdiskSize = %d\n", cdrom->capacity_in_bytes);
+
if (cdrom->lba) {
- if (cdrom->capacity_B % 2048) {
- Ramdisk_Print_CD("\t\t capacity in LBA is %d\n", cdrom->capacity_B/2048 + 1);
- return cdrom->capacity_B/2048 + 1;
+ if (cdrom->capacity_in_bytes % 2048) {
+ PrintDebug("\t\t capacity in LBA is %d\n", (cdrom->capacity_in_bytes / 2048) + 1);
+ return (cdrom->capacity_in_bytes / 2048) + 1;
} else {
- Ramdisk_Print_CD("\t\t capacity in LBA is %d\n", cdrom->capacity_B/2048);
- return cdrom->capacity_B/2048;
+ PrintDebug("\t\t capacity in LBA is %d\n", cdrom->capacity_in_bytes / 2048);
+ return cdrom->capacity_in_bytes / 2048;
}
} else {
+ PrintError("Unsupported CDROM mode in capacity query\n");
//FIXME CHS mode
return 0;
}
/*
* Read a single block from the CD
*/
-static
-void cdrom_read_block(struct cdrom_interface *cdrom, uint8* buf, int lba)// __attribute__(regparm(2));
-{
+static void cdrom_read_block(void * private_data, uint8_t * buf, int lba)/* __attribute__(regparm(2)); */ {
+ struct cdrom_state * cdrom = (struct cdrom_state *)private_data;
V3_ASSERT(lba != 0);
-
- Ramdisk_Print_CD("[cdrom_read_block] lba = %d\n", lba);
- memcpy(buf, (uint8 *)(cdrom->fd + lba*2048), 2048);
- return;
+
+ PrintDebug("[cdrom_read_block] lba = %d (cdrom_image_start=%x)\n", lba, cdrom->image_addr);
+ memcpy(buf, (uchar_t *)(cdrom->image_addr + lba * 2048), 2048);
+ PrintDebug("Returning from read block\n");
+ return;
}
+static void set_LBA(void * private_data, uchar_t lba) {
+ struct cdrom_state * cdrom = (struct cdrom_state *)private_data;
+ cdrom->lba = lba;
+}
+
+
/*
* Start (spin up) the CD.
*/
-static
-int cdrom_start(struct cdrom_interface *cdrom)
-{
- Ramdisk_Print_CD("[cdrom_start]\n");
+static int cdrom_start(void * private_data) {
+ PrintDebug("[cdrom_start]\n");
return 1;
}
-void init_cdrom(struct cdrom_interface *cdrom)
-{
- V3_ASSERT(cdrom != NULL);
+static struct cdrom_ops cd_ops = {
+ .insert_cdrom = cdrom_insert,
+ .eject_cdrom = cdrom_eject,
+ .read_toc = cdrom_read_toc,
+ .capacity = cdrom_capacity,
+ .read_block = cdrom_read_block,
+ .start_cdrom = cdrom_start,
+ .set_LBA = set_LBA,
+};
+
+
+
+
+static int cdrom_device_init(struct vm_device * dev) {
+ struct cdrom_state * cdrom = (struct cdrom_state *)dev->private_data;
+ PrintDebug("[cdrom_init]\n");
+ PrintDebug("CDIMAGE located at: %x\n", cdrom->image_addr);
+
+ //FIXME:lba
+ cdrom->lba = 1;
+
+ v3_ramdisk_register_cdrom(cdrom->ide_dev, 1, 0, &cd_ops, cdrom);
+
+ return 0;
+}
+
+
+static int cdrom_device_deinit(struct vm_device * dev) {
+ return 0;
+}
+
+static struct vm_device_ops dev_ops = {
+ .init = cdrom_device_init,
+ .deinit = cdrom_device_deinit,
+ .reset = NULL,
+ .start = NULL,
+ .stop = NULL,
+};
+
+struct vm_device * v3_create_cdrom(struct vm_device * ramdisk_dev, void * ramdisk, uint_t ramdisk_size){
+ struct cdrom_state * cd = (struct cdrom_state *)V3_Malloc(sizeof(struct cdrom_state));
+ V3_ASSERT(cd != NULL);
+
+ memset(cd, 0, sizeof(struct cdrom_state));
+
+ cd->image_addr = (uchar_t *)ramdisk;
+ cd->capacity_in_bytes = ramdisk_size;
+ cd->ide_dev = ramdisk_dev;
- cdrom->ops.init = &cdrom_init;
- cdrom->ops.insert_cdrom = &cdrom_insert;
- cdrom->ops.eject_cdrom = &cdrom_eject;
- cdrom->ops.read_toc = &cdrom_read_toc;
- cdrom->ops.capacity = &cdrom_capacity;
- cdrom->ops.read_block = &cdrom_read_block;
- cdrom->ops.start_cdrom = &cdrom_start;
+ PrintDebug("Creating RamDISK CDROM\n");
- return;
+ struct vm_device * cd_dev = create_device("Ram Based CD", &dev_ops, cd);
+
+ return cd_dev;
}
+
-
/*
* This file is part of the Palacios Virtual Machine Monitor developed
* by the V3VEE Project with funding from the United States National
* 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;
}
*/
#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));
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)
{
-
/*
*
* Copyright (C) 2002 MandrakeSoft S.A.
#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
-#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))
+static const char cdrom_str[] = "CD-ROM";
+static const char harddisk_str[] = "HARDDISK";
+static const char none_str[] = "NONE";
-#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)
+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;
+ }
+}
-#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")
+static inline void write_features(struct channel_t * channel, uchar_t value) {
+ channel->drives[0].controller.features = value;
+ channel->drives[1].controller.features = value;
+}
-#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)
+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 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;
+}
-#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)
+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;
+}
-#define PACKET_SIZE 12
+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);
-static struct ramdisk_t *ramdisk_state;
+ channel->drives[1].controller.cylinder_no &= 0x00ff;
+ channel->drives[1].controller.cylinder_no |= (val2 & 0xff00);
+}
+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 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));
+}
+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 inline struct drive_t * get_selected_drive(struct channel_t * channel) {
+ return &(channel->drives[channel->drive_select]);
+}
-/*
- * Static routines
- */
-static
-uint_t ramdisk_read_port(ushort_t port,
- void *src,
- uint_t length,
- struct vm_device *dev);
+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
-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
-uint_t ramdisk_write_port_ignore(ushort_t port,
- void *src,
- uint_t length,
- struct vm_device *dev);
+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 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
-Bit32u rd_read_handler(struct channel_t *channels, Bit32u address, unsigned io_len);
-static
-void rd_write_handler(struct channel_t *channels, Bit32u address,
- Bit32u value, unsigned io_len);
+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;
+}
-/*
- * ATAPI routines
- */
+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_identify_ATAPI_drive(struct channel_t *channels, Bit8u channel);
+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
-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 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;
+}
-static
-void rd_ready_to_send_atapi(struct channel_t *channels, Bit8u channel);
+static inline uint16_t rd_read_16bit(const uint8_t* buf) {
+ return (buf[0] << 8) | buf[1];
+}
-static
-void rd_atapi_cmd_error(struct channel_t *channels, Bit8u channel, sense_t sense_key, asc_t asc);
-static
-void rd_init_mode_sense_single(struct channel_t *channels, Bit8u channel, const void* src, int size);
-static
-void rd_atapi_cmd_nop(struct channel_t *channels, Bit8u channel);
+static inline uint32_t rd_read_32bit(const uint8_t* buf) {
+ return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+}
-static
-void rd_command_aborted(struct channel_t *channels, Bit8u channel, unsigned value);
+////////////////////////////////////////////////////////////////////////////
/*
- * Interrupt handling
+ * ATAPI routines
*/
-static
-void rd_raise_interrupt(struct channel_t *channels, Bit8u channel);
-static
-void rd_lower_irq(struct vm_device *dev, Bit32u irq);
+static void rd_init_mode_sense_single(struct vm_device * dev, struct channel_t * channel, const void * src, int size);
+static void rd_command_aborted(struct vm_device * dev, struct channel_t * channel, unsigned value);
-/*
- * Helper routines
- */
-uint16 rd_read_16bit(const uint8* buf)
-{
- return (buf[0] << 8) | buf[1];
-}
+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);
-uint32 rd_read_32bit(const uint8* buf)
-{
- return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
-}
+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);
+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);
-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)));
-
-
- 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)));
-
- 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)));
+/*
+ * 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("sizeof(channles->drives[0].controller.control) = %d\n", sizeof((channels->drives[0].controller.control)));
+/*
+ * Helper routines
+ */
- 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);
- 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);
+#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.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);
- 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);
+int v3_ramdisk_register_cdrom(struct vm_device * dev, uint_t busID, uint_t driveID, struct cdrom_ops* cd, void * private_data) {
+ struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data);
+ struct channel_t * channel = &(ramdisk->channels[busID]);
+ struct drive_t * drive = &(channel->drives[driveID]);
+ struct controller_t * controller = &(drive->controller);
- 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);
+
+ if (drive->device_type != IDE_NONE) {
+ PrintError("Device already registered at this location\n");
+ return -1;
+ }
- Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.c_d = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.c_d);
+ channel->irq = 15;
- Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.i_o = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.i_o);
+ // Make model string
+ strncpy((char*)(drive->model_no), "V3VEE Ramdisk", 40);
- Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.rel = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.rel);
+ while (strlen((char *)(drive->model_no)) < 40) {
+ strcat ((char*)(drive->model_no), " ");
+ }
+
+ PrintDebug("CDROM on target %d/%d\n", busID, driveID);
+
+ drive->device_type = IDE_CDROM;
+ drive->cdrom.locked = 0;
+ drive->sense.sense_key = SENSE_NONE;
+ drive->sense.asc = 0;
+ drive->sense.ascq = 0;
+
+ drive->private_data = private_data;
- Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.tag = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.tag);
+#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
+
+ controller->sector_count = 0;
- Ramdisk_Print("channels[%d].drives[%d].cdrom.ready = %d\n", channel, device, channels[channel].drives[device].cdrom.ready);
-
- }//for device
- }//for channel
+ drive->cdrom.cd = cd;
- return;
+ PrintDebug("\t\tCD on ata%d-%d: '%s'\n",
+ busID,
+ driveID, "");
+
+ if(drive->cdrom.cd->insert_cdrom(drive->private_data)) {
+ PrintDebug("\t\tMedia present in CD-ROM drive\n");
+ drive->cdrom.ready = 1;
+ drive->cdrom.capacity = drive->cdrom.cd->capacity(drive->private_data);
+ PrintDebug("\t\tCDROM capacity is %d\n", drive->cdrom.capacity);
+ } else {
+ PrintDebug("\t\tCould not locate CD-ROM, continuing with media not present\n");
+ drive->cdrom.ready = 0;
+ }
+
+ return 0;
}
-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) {
-
- channels[channel].ioaddr1 = 0x170;
- channels[channel].ioaddr2 = 0x370;
- channels[channel].irq = 15;
- channels[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, " ");
- }
-
- 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;
-
-
- //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;
- }
-
- 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");
- return INTR_REASON_BIT_ERR;
- }
-
-
- channels[channel].drives[device].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);
-
- struct cdrom_interface *cdif = channels[channel].drives[device].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, "");
-
- 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);
- } else {
- Ramdisk_Print("\t\tCould not locate CD-ROM, continuing with media not present\n");
- channels[channel].drives[device].cdrom.ready = 0;
- }
-
- }//if device = 0
- }//if channel = 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)
+ {
+
+ 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->read_block(drive->private_data, 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);
- 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;
+ 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;
+
+ 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 (handle_atapi_packet_command(dev, channel, *(ushort_t *)src) == -1) {
+ return -1;
}
- if (port == 0x07) {
- rd_lower_irq((struct vm_device *)(ramdisk_state->private_data), channels[channel].irq);
- }
- 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;
+ }
- // off_t logical_sector;
- // off_t ret;
+ 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;
+ /* JRL THIS NEEDS TO CHANGE */
+ return length;
+
+ }
+ return length;
+}
+
+
+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;
+ }
+
+ rd_lower_irq(dev, channel->irq);
+
+ } 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 (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;
+ }
- Bit8u channel = MAX_ATA_CHANNEL;
- Bit32u port = 0xff; // undefined
+ 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;
- Ramdisk_Print("[rd_write_handler]\n");
- // Bit8u atapi_command;
- //int alloc_length;
+ *(uchar_t *)dst = val;
+ return length;
- 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;
+ 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;
+
break;
- }
}
- 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;
+ 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;
+ }
+
+ 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);
+
+ *(uchar_t *)dst = val;
+ return length;
+
+ 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;
+ }
+
+ default:
+ PrintError("Invalid Port: %d\n", port);
+ return -1;
}
+}
- Ramdisk_Print("[W_handler] IO write to %x = %02x, channel = %d\n", (unsigned) address, (unsigned) value, channel);
- struct cdrom_interface *cdif = SELECTED_DRIVE(channel).cdrom.cd;
- switch (port) {
- case 0x00: // 0x1f0
- Ramdisk_Print("\t\twrite port 170\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) {
- //////////////////////////////////////////////////////////
- switch (SELECTED_CONTROLLER(channel).current_command) {
- case 0x30: // WRITE SECTORS
- RD_PANIC("\t\tneed to implement 0x30(write sector) to port 0x170\n");
+ 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);
+ }
- 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;
+ 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);
+
+
+
+ if (drive->cdrom.cd) {
+ PrintDebug("\t\tSetting LBA on CDROM: %d\n", (value >> 6) & 1);
+ drive->cdrom.cd->set_LBA(drive->private_data, (value >> 6) & 1);
+ }
+
+
+ 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;
+ }
- /* if packet completely writtten */
- if (SELECTED_CONTROLLER(channel).buffer_index >= PACKET_SIZE) {
- // complete command received
- Bit8u atapi_command = SELECTED_CONTROLLER(channel).buffer[0];
+ 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->start_cdrom(drive->private_data);
- 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->eject_cdrom(drive->private_data);
+
+ 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->read_toc(drive->private_data, controller->buffer,
+ &toc_length, msf, starting_track))) {
+ PrintDebug("CDROM: Reading Table of Contents Failed\n");
+ 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)) {
+ PrintError("CDROM Error: Not Ready (ATA%d/%d)\n",
+ get_channel_no(ramdisk, channel), get_drive_no(channel, drive));
+ 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);
+ PrintError("READ(%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) {
+ PrintError("CDROM Error: Capacity exceeded [capacity=%d] (ATA%d/%d)\n",
+ drive->cdrom.capacity,
+ get_channel_no(ramdisk, channel), get_drive_no(channel, drive));
+ 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) {
+ PrintError("CDROM Error: Atapi command send error\n");
+ 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)
{
- unsigned i;
+ 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)
+{
+ 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
+++ /dev/null
-api/ - The code for the high-level wrapper API. Not needed if
- you use the lowel-level call-back/raw API.
-
-core/ - The core of the TPC/IP stack; protocol implementations,
- memory and buffer management, and the low-level raw API.
-
-include/ - lwIP include files.
-
-netif/ - Generic network interface device drivers are kept here,
- as well as the ARP module.
-
-For more information on the various subdirectories, check the FILES
-file in each directory.
+++ /dev/null
-/**
- * @file
- *
- * AutoIP Automatic LinkLocal IP Configuration
- */
-
-/*
- *
- * Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
- * All rights reserved.
- *
- * 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.
- *
- * Author: Dominik Spies <kontakt@dspies.de>
- *
- * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform
- * with RFC 3927.
- *
- *
- * Please coordinate changes and requests with Dominik Spies
- * <kontakt@dspies.de>
- */
-
-#ifndef __LWIP_AUTOIP_H__
-#define __LWIP_AUTOIP_H__
-
-#include "lwip/opt.h"
-
-#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/netif.h"
-#include "lwip/udp.h"
-#include "netif/etharp.h"
-
-/* AutoIP Timing */
-#define AUTOIP_TMR_INTERVAL 100
-#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL)
-
-/* RFC 3927 Constants */
-#define PROBE_WAIT 1 /* second (initial random delay) */
-#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */
-#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */
-#define PROBE_NUM 3 /* (number of probe packets) */
-#define ANNOUNCE_NUM 2 /* (number of announcement packets) */
-#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */
-#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */
-#define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */
-#define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */
-#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */
-
-/* AutoIP client states */
-#define AUTOIP_STATE_OFF 0
-#define AUTOIP_STATE_PROBING 1
-#define AUTOIP_STATE_ANNOUNCING 2
-#define AUTOIP_STATE_BOUND 3
-
-struct autoip
-{
- struct ip_addr llipaddr; /* the currently selected, probed, announced or used LL IP-Address */
- u8_t state; /* current AutoIP state machine state */
- u8_t sent_num; /* sent number of probes or announces, dependent on state */
- u16_t ttw; /* ticks to wait, tick is AUTOIP_TMR_INTERVAL long */
- u8_t lastconflict; /* ticks until a conflict can be solved by defending */
- u8_t tried_llipaddr; /* total number of probed/used Link Local IP-Addresses */
-};
-
-
-/** Init srand, has to be called before entering mainloop */
-void autoip_init(void);
-
-/** Start AutoIP client */
-err_t autoip_start(struct netif *netif);
-
-/** Stop AutoIP client */
-err_t autoip_stop(struct netif *netif);
-
-/** Handles every incoming ARP Packet, called by etharp_arp_input */
-void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr);
-
-/** Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds */
-void autoip_tmr(void);
-
-#endif /* LWIP_AUTOIP */
-
-#endif /* __LWIP_AUTOIP_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_ICMP_H__
-#define __LWIP_ICMP_H__
-
-#include "lwip/opt.h"
-
-#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ICMP_ER 0 /* echo reply */
-#define ICMP_DUR 3 /* destination unreachable */
-#define ICMP_SQ 4 /* source quench */
-#define ICMP_RD 5 /* redirect */
-#define ICMP_ECHO 8 /* echo */
-#define ICMP_TE 11 /* time exceeded */
-#define ICMP_PP 12 /* parameter problem */
-#define ICMP_TS 13 /* timestamp */
-#define ICMP_TSR 14 /* timestamp reply */
-#define ICMP_IRQ 15 /* information request */
-#define ICMP_IR 16 /* information reply */
-
-enum icmp_dur_type {
- ICMP_DUR_NET = 0, /* net unreachable */
- ICMP_DUR_HOST = 1, /* host unreachable */
- ICMP_DUR_PROTO = 2, /* protocol unreachable */
- ICMP_DUR_PORT = 3, /* port unreachable */
- ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */
- ICMP_DUR_SR = 5 /* source route failed */
-};
-
-enum icmp_te_type {
- ICMP_TE_TTL = 0, /* time to live exceeded in transit */
- ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */
-};
-
-void icmp_input(struct pbuf *p, struct netif *inp);
-
-void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
-void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct icmp_echo_hdr {
- PACK_STRUCT_FIELD(u16_t _type_code);
- PACK_STRUCT_FIELD(u16_t chksum);
- PACK_STRUCT_FIELD(u16_t id);
- PACK_STRUCT_FIELD(u16_t seqno);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-
-PACK_STRUCT_BEGIN
-struct icmp_dur_hdr {
- PACK_STRUCT_FIELD(u16_t _type_code);
- PACK_STRUCT_FIELD(u16_t chksum);
- PACK_STRUCT_FIELD(u32_t unused);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-
-PACK_STRUCT_BEGIN
-struct icmp_te_hdr {
- PACK_STRUCT_FIELD(u16_t _type_code);
- PACK_STRUCT_FIELD(u16_t chksum);
- PACK_STRUCT_FIELD(u32_t unused);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-#define ICMPH_TYPE(hdr) (ntohs((hdr)->_type_code) >> 8)
-#define ICMPH_CODE(hdr) (ntohs((hdr)->_type_code) & 0xff)
-
-#define ICMPH_TYPE_SET(hdr, type) ((hdr)->_type_code = htons(ICMPH_CODE(hdr) | ((type) << 8)))
-#define ICMPH_CODE_SET(hdr, code) ((hdr)->_type_code = htons((code) | (ICMPH_TYPE(hdr) << 8)))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_ICMP */
-
-#endif /* __LWIP_ICMP_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2002 CITEL Technologies Ltd.
- * All rights reserved.
- *
- * 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. Neither the name of CITEL Technologies Ltd nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES 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 CITEL TECHNOLOGIES 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.
- *
- * This file is a contribution to the lwIP TCP/IP stack.
- * The Swedish Institute of Computer Science and Adam Dunkels
- * are specifically granted permission to redistribute this
- * source code.
-*/
-
-#ifndef __LWIP_IGMP_H__
-#define __LWIP_IGMP_H__
-
-#include "lwip/opt.h"
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/pbuf.h"
-
-#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * IGMP constants
- */
-#define IP_PROTO_IGMP 2
-#define IGMP_TTL 1
-#define IGMP_MINLEN 8
-#define ROUTER_ALERT 0x9404
-#define ROUTER_ALERTLEN 4
-
-/*
- * IGMP message types, including version number.
- */
-#define IGMP_MEMB_QUERY 0x11 /* Membership query */
-#define IGMP_V1_MEMB_REPORT 0x12 /* Ver. 1 membership report */
-#define IGMP_V2_MEMB_REPORT 0x16 /* Ver. 2 membership report */
-#define IGMP_LEAVE_GROUP 0x17 /* Leave-group message */
-
-/* IGMP timer */
-#define IGMP_TMR_INTERVAL 100 /* Milliseconds */
-#define IGMP_V1_DELAYING_MEMBER_TMR (1000/IGMP_TMR_INTERVAL)
-#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL)
-
-/* MAC Filter Actions */
-#define IGMP_DEL_MAC_FILTER 0
-#define IGMP_ADD_MAC_FILTER 1
-
-/* Group membership states */
-#define IGMP_GROUP_NON_MEMBER 0
-#define IGMP_GROUP_DELAYING_MEMBER 1
-#define IGMP_GROUP_IDLE_MEMBER 2
-
-/*
- * IGMP packet format.
- */
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct igmp_msg {
- PACK_STRUCT_FIELD(u8_t igmp_msgtype);
- PACK_STRUCT_FIELD(u8_t igmp_maxresp);
- PACK_STRUCT_FIELD(u16_t igmp_checksum);
- PACK_STRUCT_FIELD(struct ip_addr igmp_group_address);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-/*
- * now a group structure - there is
- * a list of groups for each interface
- * these should really be linked from the interface, but
- * if we keep them separate we will not affect the lwip original code
- * too much
- *
- * There will be a group for the all systems group address but this
- * will not run the state machine as it is used to kick off reports
- * from all the other groups
- */
-
-struct igmp_group {
- struct igmp_group *next;
- struct netif *interface;
- struct ip_addr group_address;
- u8_t last_reporter_flag; /* signifies we were the last person to report */
- u8_t group_state;
- u16_t timer;
- u8_t use; /* counter of simultaneous uses */
-};
-
-
-/* Prototypes */
-void igmp_init(void);
-
-err_t igmp_start( struct netif *netif);
-
-err_t igmp_stop( struct netif *netif);
-
-void igmp_report_groups( struct netif *netif);
-
-struct igmp_group *igmp_lookfor_group( struct netif *ifp, struct ip_addr *addr);
-
-struct igmp_group *igmp_lookup_group( struct netif *ifp, struct ip_addr *addr);
-
-err_t igmp_remove_group( struct igmp_group *group);
-
-void igmp_input( struct pbuf *p, struct netif *inp, struct ip_addr *dest);
-
-err_t igmp_joingroup( struct ip_addr *ifaddr, struct ip_addr *groupaddr);
-
-err_t igmp_leavegroup( struct ip_addr *ifaddr, struct ip_addr *groupaddr);
-
-void igmp_tmr(void);
-
-void igmp_timeout( struct igmp_group *group);
-
-void igmp_start_timer( struct igmp_group *group, u8_t max_time);
-
-void igmp_stop_timer( struct igmp_group *group);
-
-void igmp_delaying_member( struct igmp_group *group, u8_t maxresp);
-
-err_t igmp_ip_output_if( struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, u8_t ttl, u8_t proto, struct netif *netif);
-
-void igmp_send( struct igmp_group *group, u8_t type);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_IGMP */
-
-#endif /* __LWIP_IGMP_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_INET_H__
-#define __LWIP_INET_H__
-
-#include "lwip/opt.h"
-
-#include "lwip/ip_addr.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-u32_t inet_addr(const char *cp);
-int inet_aton(const char *cp, struct in_addr *addr);
-char *inet_ntoa(struct in_addr addr); /* returns ptr to static buffer; not reentrant! */
-
-#ifdef htons
-#undef htons
-#endif /* htons */
-#ifdef htonl
-#undef htonl
-#endif /* htonl */
-#ifdef ntohs
-#undef ntohs
-#endif /* ntohs */
-#ifdef ntohl
-#undef ntohl
-#endif /* ntohl */
-
-#ifndef LWIP_PLATFORM_BYTESWAP
-#define LWIP_PLATFORM_BYTESWAP 0
-#endif
-
-#if BYTE_ORDER == BIG_ENDIAN
-#define htons(x) (x)
-#define ntohs(x) (x)
-#define htonl(x) (x)
-#define ntohl(x) (x)
-#else /* BYTE_ORDER != BIG_ENDIAN */
-#ifdef LWIP_PREFIX_BYTEORDER_FUNCS
-/* workaround for naming collisions on some platforms */
-#define htons lwip_htons
-#define ntohs lwip_ntohs
-#define htonl lwip_htonl
-#define ntohl lwip_ntohl
-#endif /* LWIP_PREFIX_BYTEORDER_FUNCS */
-#if LWIP_PLATFORM_BYTESWAP
-#define htons(x) LWIP_PLATFORM_HTONS(x)
-#define ntohs(x) LWIP_PLATFORM_HTONS(x)
-#define htonl(x) LWIP_PLATFORM_HTONL(x)
-#define ntohl(x) LWIP_PLATFORM_HTONL(x)
-#else /* LWIP_PLATFORM_BYTESWAP */
-u16_t htons(u16_t x);
-u16_t ntohs(u16_t x);
-u32_t htonl(u32_t x);
-u32_t ntohl(u32_t x);
-#endif /* LWIP_PLATFORM_BYTESWAP */
-
-#endif /* BYTE_ORDER == BIG_ENDIAN */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_INET_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_INET_CHKSUM_H__
-#define __LWIP_INET_CHKSUM_H__
-
-#include "lwip/opt.h"
-
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-u16_t inet_chksum(void *dataptr, u16_t len);
-u16_t inet_chksum_pbuf(struct pbuf *p);
-u16_t inet_chksum_pseudo(struct pbuf *p,
- struct ip_addr *src, struct ip_addr *dest,
- u8_t proto, u16_t proto_len);
-u16_t inet_chksum_pseudo_partial(struct pbuf *p,
- struct ip_addr *src, struct ip_addr *dest,
- u8_t proto, u16_t proto_len, u16_t chksum_len);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_INET_H__ */
-
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Jani Monoses <jani@iv.ro>
- *
- */
-
-#ifndef __LWIP_IP_FRAG_H__
-#define __LWIP_IP_FRAG_H__
-
-#include "lwip/opt.h"
-#include "lwip/err.h"
-#include "lwip/pbuf.h"
-#include "lwip/netif.h"
-#include "lwip/ip_addr.h"
-#include "lwip/ip.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if IP_REASSEMBLY
-/* The IP reassembly timer interval in milliseconds. */
-#define IP_TMR_INTERVAL 1000
-
-/* IP reassembly helper struct.
- * This is exported because memp needs to know the size.
- */
-struct ip_reassdata {
- struct ip_reassdata *next;
- struct pbuf *p;
- struct ip_hdr iphdr;
- u16_t datagram_len;
- u8_t flags;
- u8_t timer;
-};
-
-void ip_reass_init(void);
-void ip_reass_tmr(void);
-struct pbuf * ip_reass(struct pbuf *p);
-#endif /* IP_REASSEMBLY */
-
-#if IP_FRAG
-err_t ip_frag(struct pbuf *p, struct netif *netif, struct ip_addr *dest);
-#endif /* IP_FRAG */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_IP_FRAG_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_ICMP_H__
-#define __LWIP_ICMP_H__
-
-#include "lwip/opt.h"
-
-#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/pbuf.h"
-#include "lwip/netif.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ICMP6_DUR 1
-#define ICMP6_TE 3
-#define ICMP6_ECHO 128 /* echo */
-#define ICMP6_ER 129 /* echo reply */
-
-
-enum icmp_dur_type {
- ICMP_DUR_NET = 0, /* net unreachable */
- ICMP_DUR_HOST = 1, /* host unreachable */
- ICMP_DUR_PROTO = 2, /* protocol unreachable */
- ICMP_DUR_PORT = 3, /* port unreachable */
- ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */
- ICMP_DUR_SR = 5 /* source route failed */
-};
-
-enum icmp_te_type {
- ICMP_TE_TTL = 0, /* time to live exceeded in transit */
- ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */
-};
-
-void icmp_input(struct pbuf *p, struct netif *inp);
-
-void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
-void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
-
-struct icmp_echo_hdr {
- u8_t type;
- u8_t icode;
- u16_t chksum;
- u16_t id;
- u16_t seqno;
-};
-
-struct icmp_dur_hdr {
- u8_t type;
- u8_t icode;
- u16_t chksum;
- u32_t unused;
-};
-
-struct icmp_te_hdr {
- u8_t type;
- u8_t icode;
- u16_t chksum;
- u32_t unused;
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_ICMP */
-
-#endif /* __LWIP_ICMP_H__ */
-
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_IP_H__
-#define __LWIP_IP_H__
-
-#include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-
-#include "lwip/err.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define IP_HLEN 40
-
-#define IP_PROTO_ICMP 58
-#define IP_PROTO_UDP 17
-#define IP_PROTO_UDPLITE 136
-#define IP_PROTO_TCP 6
-
-/* This is passed as the destination address to ip_output_if (not
- to ip_output), meaning that an IP header already is constructed
- in the pbuf. This is used when TCP retransmits. */
-#ifdef IP_HDRINCL
-#undef IP_HDRINCL
-#endif /* IP_HDRINCL */
-#define IP_HDRINCL NULL
-
-#if LWIP_NETIF_HWADDRHINT
-#define IP_PCB_ADDRHINT ;u8_t addr_hint
-#else
-#define IP_PCB_ADDRHINT
-#endif /* LWIP_NETIF_HWADDRHINT */
-
-/* This is the common part of all PCB types. It needs to be at the
- beginning of a PCB type definition. It is located here so that
- changes to this common part are made in one location instead of
- having to change all PCB structs. */
-#define IP_PCB struct ip_addr local_ip; \
- struct ip_addr remote_ip; \
- /* Socket options */ \
- u16_t so_options; \
- /* Type Of Service */ \
- u8_t tos; \
- /* Time To Live */ \
- u8_t ttl; \
- /* link layer address resolution hint */ \
- IP_PCB_ADDRHINT
-
-
-/* The IPv6 header. */
-struct ip_hdr {
-#if BYTE_ORDER == LITTLE_ENDIAN
- u8_t tclass1:4, v:4;
- u8_t flow1:4, tclass2:4;
-#else
- u8_t v:4, tclass1:4;
- u8_t tclass2:8, flow1:4;
-#endif
- u16_t flow2;
- u16_t len; /* payload length */
- u8_t nexthdr; /* next header */
- u8_t hoplim; /* hop limit (TTL) */
- struct ip_addr src, dest; /* source and destination IP addresses */
-};
-
-#define IPH_PROTO(hdr) (iphdr->nexthdr)
-
-void ip_init(void);
-
-#include "lwip/netif.h"
-
-struct netif *ip_route(struct ip_addr *dest);
-
-void ip_input(struct pbuf *p, struct netif *inp);
-
-/* source and destination addresses in network byte order, please */
-err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
- u8_t ttl, u8_t proto);
-
-err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
- u8_t ttl, u8_t proto,
- struct netif *netif);
-
-#if IP_DEBUG
-void ip_debug_print(struct pbuf *p);
-#endif /* IP_DEBUG */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_IP_H__ */
-
-
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_IP_ADDR_H__
-#define __LWIP_IP_ADDR_H__
-
-#include "lwip/opt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define IP_ADDR_ANY 0
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
- struct ip_addr {
- PACK_STRUCT_FIELD(u32_t addr[4]);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-/*
- * struct ipaddr2 is used in the definition of the ARP packet format in
- * order to support compilers that don't have structure packing.
- */
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct ip_addr2 {
- PACK_STRUCT_FIELD(u16_t addrw[2]);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-#define IP6_ADDR(ipaddr, a,b,c,d,e,f,g,h) do { (ipaddr)->addr[0] = htonl((u32_t)((a & 0xffff) << 16) | (b & 0xffff)); \
- (ipaddr)->addr[1] = htonl(((c & 0xffff) << 16) | (d & 0xffff)); \
- (ipaddr)->addr[2] = htonl(((e & 0xffff) << 16) | (f & 0xffff)); \
- (ipaddr)->addr[3] = htonl(((g & 0xffff) << 16) | (h & 0xffff)); } while(0)
-
-u8_t ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2,
- struct ip_addr *mask);
-u8_t ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2);
-void ip_addr_set(struct ip_addr *dest, struct ip_addr *src);
-u8_t ip_addr_isany(struct ip_addr *addr);
-
-#define ip_addr_debug_print(debug, ipaddr) \
- LWIP_DEBUGF(debug, ("%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F"\n", \
- (ntohl(ipaddr->addr[0]) >> 16) & 0xffff, \
- ntohl(ipaddr->addr[0]) & 0xffff, \
- (ntohl(ipaddr->addr[1]) >> 16) & 0xffff, \
- ntohl(ipaddr->addr[1]) & 0xffff, \
- (ntohl(ipaddr->addr[2]) >> 16) & 0xffff, \
- ntohl(ipaddr->addr[2]) & 0xffff, \
- (ntohl(ipaddr->addr[3]) >> 16) & 0xffff, \
- ntohl(ipaddr->addr[3]) & 0xffff));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_IP_ADDR_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_API_H__
-#define __LWIP_API_H__
-
-#include "lwip/opt.h"
-
-#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/netbuf.h"
-#include "lwip/sys.h"
-#include "lwip/ip_addr.h"
-#include "lwip/err.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Throughout this file, IP addresses and port numbers are expected to be in
- * the same byte order as in the corresponding pcb.
- */
-
-/* Flags for netconn_write */
-#define NETCONN_NOFLAG 0x00
-#define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */
-#define NETCONN_COPY 0x01
-#define NETCONN_MORE 0x02
-
-/* Helpers to process several netconn_types by the same code */
-#define NETCONNTYPE_GROUP(t) (t&0xF0)
-#define NETCONNTYPE_DATAGRAM(t) (t&0xE0)
-
-enum netconn_type {
- NETCONN_INVALID = 0,
- /* NETCONN_TCP Group */
- NETCONN_TCP = 0x10,
- /* NETCONN_UDP Group */
- NETCONN_UDP = 0x20,
- NETCONN_UDPLITE = 0x21,
- NETCONN_UDPNOCHKSUM= 0x22,
- /* NETCONN_RAW Group */
- NETCONN_RAW = 0x40
-};
-
-enum netconn_state {
- NETCONN_NONE,
- NETCONN_WRITE,
- NETCONN_LISTEN,
- NETCONN_CONNECT,
- NETCONN_CLOSE
-};
-
-enum netconn_evt {
- NETCONN_EVT_RCVPLUS,
- NETCONN_EVT_RCVMINUS,
- NETCONN_EVT_SENDPLUS,
- NETCONN_EVT_SENDMINUS
-};
-
-#if LWIP_IGMP
-enum netconn_igmp {
- NETCONN_JOIN,
- NETCONN_LEAVE
-};
-#endif /* LWIP_IGMP */
-
-/* forward-declare some structs to avoid to include their headers */
-struct ip_pcb;
-struct tcp_pcb;
-struct udp_pcb;
-struct raw_pcb;
-struct netconn;
-
-/** A callback prototype to inform about events for a netconn */
-typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len);
-
-/** A netconn descriptor */
-struct netconn {
- /** type of the netconn (TCP, UDP or RAW) */
- enum netconn_type type;
- /** current state of the netconn */
- enum netconn_state state;
- /** the lwIP internal protocol control block */
- union {
- struct ip_pcb *ip;
- struct tcp_pcb *tcp;
- struct udp_pcb *udp;
- struct raw_pcb *raw;
- } pcb;
- /** the last error this netconn had */
- err_t err;
- /** sem that is used to synchroneously execute functions in the core context */
- sys_sem_t op_completed;
- /** mbox where received packets are stored until they are fetched
- by the netconn application thread (can grow quite big) */
- sys_mbox_t recvmbox;
- /** mbox where new connections are stored until processed
- by the application thread */
- sys_mbox_t acceptmbox;
- /** only used for socket layer */
- int socket;
-#if LWIP_SO_RCVTIMEO
- /** timeout to wait for new data to be received
- (or connections to arrive for listening netconns) */
- int recv_timeout;
-#endif /* LWIP_SO_RCVTIMEO */
-#if LWIP_SO_RCVBUF
- /** maximum amount of bytes queued in recvmbox */
- int recv_bufsize;
-#endif /* LWIP_SO_RCVBUF */
- u16_t recv_avail;
- /** TCP: when data passed to netconn_write doesn't fit into the send buffer,
- this temporarily stores the message. */
- struct api_msg_msg *write_msg;
- /** TCP: when data passed to netconn_write doesn't fit into the send buffer,
- this temporarily stores how much is already sent. */
- int write_offset;
-#if LWIP_TCPIP_CORE_LOCKING
- /** TCP: when data passed to netconn_write doesn't fit into the send buffer,
- this temporarily stores whether to wake up the original application task
- if data couldn't be sent in the first try. */
- u8_t write_delayed;
-#endif /* LWIP_TCPIP_CORE_LOCKING */
- /** A callback function that is informed about events for this netconn */
- netconn_callback callback;
-};
-
-/* Register an Network connection event */
-#define API_EVENT(c,e,l) if (c->callback) { \
- (*c->callback)(c, e, l); \
- }
-
-/* Network connection functions: */
-#define netconn_new(t) netconn_new_with_proto_and_callback(t, 0, NULL)
-#define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c)
-struct
-netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto,
- netconn_callback callback);
-err_t netconn_delete (struct netconn *conn);
-enum netconn_type netconn_type (struct netconn *conn);
-
-err_t netconn_getaddr (struct netconn *conn,
- struct ip_addr *addr,
- u16_t *port,
- u8_t local);
-#define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0)
-#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1)
-
-err_t netconn_bind (struct netconn *conn,
- struct ip_addr *addr,
- u16_t port);
-err_t netconn_connect (struct netconn *conn,
- struct ip_addr *addr,
- u16_t port);
-err_t netconn_disconnect (struct netconn *conn);
-err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog);
-#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG)
-struct netconn * netconn_accept (struct netconn *conn);
-struct netbuf * netconn_recv (struct netconn *conn);
-err_t netconn_sendto (struct netconn *conn,
- struct netbuf *buf, struct ip_addr *addr, u16_t port);
-err_t netconn_send (struct netconn *conn,
- struct netbuf *buf);
-err_t netconn_write (struct netconn *conn,
- const void *dataptr, int size,
- u8_t apiflags);
-err_t netconn_close (struct netconn *conn);
-
-#if LWIP_IGMP
-err_t netconn_join_leave_group (struct netconn *conn,
- struct ip_addr *multiaddr,
- struct ip_addr *interface,
- enum netconn_igmp join_or_leave);
-#endif /* LWIP_IGMP */
-#if LWIP_DNS
-err_t netconn_gethostbyname(const char *name, struct ip_addr *addr);
-#endif /* LWIP_DNS */
-
-#define netconn_err(conn) ((conn)->err)
-#define netconn_recv_bufsize(conn) ((conn)->recv_bufsize)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_NETCONN */
-
-#endif /* __LWIP_API_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_API_MSG_H__
-#define __LWIP_API_MSG_H__
-
-#include "lwip/opt.h"
-
-#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/ip_addr.h"
-#include "lwip/err.h"
-#include "lwip/sys.h"
-#include "lwip/igmp.h"
-#include "lwip/api.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* IP addresses and port numbers are expected to be in
- * the same byte order as in the corresponding pcb.
- */
-/** This struct includes everything that is necessary to execute a function
- for a netconn in another thread context (mainly used to process netconns
- in the tcpip_thread context to be thread safe). */
-struct api_msg_msg {
- /** The netconn which to process - always needed: it includes the semaphore
- which is used to block the application thread until the function finished. */
- struct netconn *conn;
- /** Depending on the executed function, one of these union members is used */
- union {
- /** used for do_send */
- struct netbuf *b;
- /** used for do_newconn */
- struct {
- u8_t proto;
- } n;
- /** used for do_bind and do_connect */
- struct {
- struct ip_addr *ipaddr;
- u16_t port;
- } bc;
- /** used for do_getaddr */
- struct {
- struct ip_addr *ipaddr;
- u16_t *port;
- u8_t local;
- } ad;
- /** used for do_write */
- struct {
- const void *dataptr;
- int len;
- u8_t apiflags;
- } w;
- /** used ofr do_recv */
- struct {
- u16_t len;
- } r;
-#if LWIP_IGMP
- /** used for do_join_leave_group */
- struct {
- struct ip_addr *multiaddr;
- struct ip_addr *interface;
- enum netconn_igmp join_or_leave;
- } jl;
-#endif /* LWIP_IGMP */
-#if TCP_LISTEN_BACKLOG
- struct {
- u8_t backlog;
- } lb;
-#endif /* TCP_LISTEN_BACKLOG */
- } msg;
-};
-
-/** This struct contains a function to execute in another thread context and
- a struct api_msg_msg that serves as an argument for this function.
- This is passed to tcpip_apimsg to execute functions in tcpip_thread context. */
-struct api_msg {
- /** function to execute in tcpip_thread context */
- void (* function)(struct api_msg_msg *msg);
- /** arguments for this function */
- struct api_msg_msg msg;
-};
-
-#if LWIP_DNS
-/** As do_gethostbyname requires more arguments but doesn't require a netconn,
- it has its own struct (to avoid struct api_msg getting bigger than necessary).
- do_gethostbyname must be called using tcpip_callback instead of tcpip_apimsg
- (see netconn_gethostbyname). */
-struct dns_api_msg {
- /** Hostname to query or dotted IP address string */
- const char *name;
- /** Rhe resolved address is stored here */
- struct ip_addr *addr;
- /** This semaphore is posted when the name is resolved, the application thread
- should wait on it. */
- sys_sem_t sem;
- /** Errors are given back here */
- err_t *err;
-};
-#endif /* LWIP_DNS */
-
-void do_newconn ( struct api_msg_msg *msg);
-void do_delconn ( struct api_msg_msg *msg);
-void do_bind ( struct api_msg_msg *msg);
-void do_connect ( struct api_msg_msg *msg);
-void do_disconnect ( struct api_msg_msg *msg);
-void do_listen ( struct api_msg_msg *msg);
-void do_send ( struct api_msg_msg *msg);
-void do_recv ( struct api_msg_msg *msg);
-void do_write ( struct api_msg_msg *msg);
-void do_getaddr ( struct api_msg_msg *msg);
-void do_close ( struct api_msg_msg *msg);
-#if LWIP_IGMP
-void do_join_leave_group( struct api_msg_msg *msg);
-#endif /* LWIP_IGMP */
-
-#if LWIP_DNS
-void do_gethostbyname(void *arg);
-#endif /* LWIP_DNS */
-
-struct netconn* netconn_alloc(enum netconn_type t, netconn_callback callback);
-void netconn_free(struct netconn *conn);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_NETCONN */
-
-#endif /* __LWIP_API_MSG_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_DEBUG_H__
-#define __LWIP_DEBUG_H__
-
-#include "lwip/arch.h"
-
-/** lower two bits indicate debug level
- * - 0 off
- * - 1 warning
- * - 2 serious
- * - 3 severe
- */
-#define LWIP_DBG_LEVEL_OFF 0x00
-#define LWIP_DBG_LEVEL_WARNING 0x01 /* bad checksums, dropped packets, ... */
-#define LWIP_DBG_LEVEL_SERIOUS 0x02 /* memory allocation failures, ... */
-#define LWIP_DBG_LEVEL_SEVERE 0x03
-#define LWIP_DBG_MASK_LEVEL 0x03
-
-/** flag for LWIP_DEBUGF to enable that debug message */
-#define LWIP_DBG_ON 0x80U
-/** flag for LWIP_DEBUGF to disable that debug message */
-#define LWIP_DBG_OFF 0x00U
-
-/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */
-#define LWIP_DBG_TRACE 0x40U
-/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */
-#define LWIP_DBG_STATE 0x20U
-/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */
-#define LWIP_DBG_FRESH 0x10U
-/** flag for LWIP_DEBUGF to halt after printing this debug message */
-#define LWIP_DBG_HALT 0x08U
-
-#ifndef LWIP_NOASSERT
-#define LWIP_ASSERT(x,y) do { if(!(y)) LWIP_PLATFORM_ASSERT(x); } while(0)
-#else /* LWIP_NOASSERT */
-#define LWIP_ASSERT(x,y)
-#endif /* LWIP_NOASSERT */
-
-/** print "m" message only if "e" is true, and execute "h" expression */
-#ifndef LWIP_ERROR
-#define LWIP_ERROR(m,e,h) do { if (!(e)) { LWIP_PLATFORM_ASSERT(m); h;}} while(0)
-#endif /* LWIP_ERROR */
-
-#ifdef LWIP_DEBUG
-/** print debug message only if debug message type is enabled...
- * AND is of correct type AND is at least LWIP_DBG_LEVEL
- */
-#define LWIP_DEBUGF(debug,x) do { \
- if ( \
- ((debug) & LWIP_DBG_ON) && \
- ((debug) & LWIP_DBG_TYPES_ON) && \
- ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \
- LWIP_PLATFORM_DIAG(x); \
- if ((debug) & LWIP_DBG_HALT) { \
- while(1); \
- } \
- } \
- } while(0)
-
-#else /* LWIP_DEBUG */
-#define LWIP_DEBUGF(debug,x)
-#endif /* LWIP_DEBUG */
-
-#endif /* __LWIP_DEBUG_H__ */
-
+++ /dev/null
-/** @file
- */
-
-#ifndef __LWIP_DHCP_H__
-#define __LWIP_DHCP_H__
-
-#include "lwip/opt.h"
-
-#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/netif.h"
-#include "lwip/udp.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** period (in seconds) of the application calling dhcp_coarse_tmr() */
-#define DHCP_COARSE_TIMER_SECS 60
-/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */
-#define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS*1000)
-/** period (in milliseconds) of the application calling dhcp_fine_tmr() */
-#define DHCP_FINE_TIMER_MSECS 500
-
-struct dhcp
-{
- /** current DHCP state machine state */
- u8_t state;
- /** retries of current request */
- u8_t tries;
- /** transaction identifier of last sent request */
- u32_t xid;
- /** our connection to the DHCP server */
- struct udp_pcb *pcb;
- /** (first) pbuf of incoming msg */
- struct pbuf *p;
- /** incoming msg */
- struct dhcp_msg *msg_in;
- /** incoming msg options */
- struct dhcp_msg *options_in;
- /** ingoing msg options length */
- u16_t options_in_len;
-
- struct pbuf *p_out; /* pbuf of outcoming msg */
- struct dhcp_msg *msg_out; /* outgoing msg */
- u16_t options_out_len; /* outgoing msg options length */
- u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */
- u16_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */
- u16_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */
- struct ip_addr server_ip_addr; /* dhcp server address that offered this lease */
- struct ip_addr offered_ip_addr;
- struct ip_addr offered_sn_mask;
- struct ip_addr offered_gw_addr;
- struct ip_addr offered_bc_addr;
-#define DHCP_MAX_DNS 2
- u32_t dns_count; /* actual number of DNS servers obtained */
- struct ip_addr offered_dns_addr[DHCP_MAX_DNS]; /* DNS server addresses */
-
- u32_t offered_t0_lease; /* lease period (in seconds) */
- u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */
- u32_t offered_t2_rebind; /* recommended rebind time (usually 66% of lease period) */
-#if LWIP_DHCP_AUTOIP_COOP
- u8_t autoip_coop_state;
-#endif
-/** Patch #1308
- * TODO: See dhcp.c "TODO"s
- */
-#if 0
- struct ip_addr offered_si_addr;
- u8_t *boot_file_name;
-#endif
-};
-
-/* MUST be compiled with "pack structs" or equivalent! */
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-/** minimum set of fields of any DHCP message */
-struct dhcp_msg
-{
- PACK_STRUCT_FIELD(u8_t op);
- PACK_STRUCT_FIELD(u8_t htype);
- PACK_STRUCT_FIELD(u8_t hlen);
- PACK_STRUCT_FIELD(u8_t hops);
- PACK_STRUCT_FIELD(u32_t xid);
- PACK_STRUCT_FIELD(u16_t secs);
- PACK_STRUCT_FIELD(u16_t flags);
- PACK_STRUCT_FIELD(struct ip_addr ciaddr);
- PACK_STRUCT_FIELD(struct ip_addr yiaddr);
- PACK_STRUCT_FIELD(struct ip_addr siaddr);
- PACK_STRUCT_FIELD(struct ip_addr giaddr);
-#define DHCP_CHADDR_LEN 16U
- PACK_STRUCT_FIELD(u8_t chaddr[DHCP_CHADDR_LEN]);
-#define DHCP_SNAME_LEN 64U
- PACK_STRUCT_FIELD(u8_t sname[DHCP_SNAME_LEN]);
-#define DHCP_FILE_LEN 128U
- PACK_STRUCT_FIELD(u8_t file[DHCP_FILE_LEN]);
- PACK_STRUCT_FIELD(u32_t cookie);
-#define DHCP_MIN_OPTIONS_LEN 68U
-/** make sure user does not configure this too small */
-#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN))
-# undef DHCP_OPTIONS_LEN
-#endif
-/** allow this to be configured in lwipopts.h, but not too small */
-#if (!defined(DHCP_OPTIONS_LEN))
-/** set this to be sufficient for your options in outgoing DHCP msgs */
-# define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN
-#endif
- PACK_STRUCT_FIELD(u8_t options[DHCP_OPTIONS_LEN]);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-/** start DHCP configuration */
-err_t dhcp_start(struct netif *netif);
-/** enforce early lease renewal (not needed normally)*/
-err_t dhcp_renew(struct netif *netif);
-/** release the DHCP lease, usually called before dhcp_stop()*/
-err_t dhcp_release(struct netif *netif);
-/** stop DHCP configuration */
-void dhcp_stop(struct netif *netif);
-/** inform server of our manual IP address */
-void dhcp_inform(struct netif *netif);
-
-/** if enabled, check whether the offered IP address is not in use, using ARP */
-#if DHCP_DOES_ARP_CHECK
-void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr);
-#endif
-
-/** to be called every minute */
-void dhcp_coarse_tmr(void);
-/** to be called every half second */
-void dhcp_fine_tmr(void);
-
-/** DHCP message item offsets and length */
-#define DHCP_MSG_OFS (UDP_DATA_OFS)
- #define DHCP_OP_OFS (DHCP_MSG_OFS + 0)
- #define DHCP_HTYPE_OFS (DHCP_MSG_OFS + 1)
- #define DHCP_HLEN_OFS (DHCP_MSG_OFS + 2)
- #define DHCP_HOPS_OFS (DHCP_MSG_OFS + 3)
- #define DHCP_XID_OFS (DHCP_MSG_OFS + 4)
- #define DHCP_SECS_OFS (DHCP_MSG_OFS + 8)
- #define DHCP_FLAGS_OFS (DHCP_MSG_OFS + 10)
- #define DHCP_CIADDR_OFS (DHCP_MSG_OFS + 12)
- #define DHCP_YIADDR_OFS (DHCP_MSG_OFS + 16)
- #define DHCP_SIADDR_OFS (DHCP_MSG_OFS + 20)
- #define DHCP_GIADDR_OFS (DHCP_MSG_OFS + 24)
- #define DHCP_CHADDR_OFS (DHCP_MSG_OFS + 28)
- #define DHCP_SNAME_OFS (DHCP_MSG_OFS + 44)
- #define DHCP_FILE_OFS (DHCP_MSG_OFS + 108)
-#define DHCP_MSG_LEN 236
-
-#define DHCP_COOKIE_OFS (DHCP_MSG_OFS + DHCP_MSG_LEN)
-#define DHCP_OPTIONS_OFS (DHCP_MSG_OFS + DHCP_MSG_LEN + 4)
-
-#define DHCP_CLIENT_PORT 68
-#define DHCP_SERVER_PORT 67
-
-/** DHCP client states */
-#define DHCP_REQUESTING 1
-#define DHCP_INIT 2
-#define DHCP_REBOOTING 3
-#define DHCP_REBINDING 4
-#define DHCP_RENEWING 5
-#define DHCP_SELECTING 6
-#define DHCP_INFORMING 7
-#define DHCP_CHECKING 8
-#define DHCP_PERMANENT 9
-#define DHCP_BOUND 10
-/** not yet implemented #define DHCP_RELEASING 11 */
-#define DHCP_BACKING_OFF 12
-#define DHCP_OFF 13
-
-/** AUTOIP cooperatation flags */
-#define DHCP_AUTOIP_COOP_STATE_OFF 0
-#define DHCP_AUTOIP_COOP_STATE_ON 1
-
-#define DHCP_BOOTREQUEST 1
-#define DHCP_BOOTREPLY 2
-
-#define DHCP_DISCOVER 1
-#define DHCP_OFFER 2
-#define DHCP_REQUEST 3
-#define DHCP_DECLINE 4
-#define DHCP_ACK 5
-#define DHCP_NAK 6
-#define DHCP_RELEASE 7
-#define DHCP_INFORM 8
-
-#define DHCP_HTYPE_ETH 1
-
-#define DHCP_HLEN_ETH 6
-
-#define DHCP_BROADCAST_FLAG 15
-#define DHCP_BROADCAST_MASK (1 << DHCP_FLAG_BROADCAST)
-
-/** BootP options */
-#define DHCP_OPTION_PAD 0
-#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */
-#define DHCP_OPTION_ROUTER 3
-#define DHCP_OPTION_DNS_SERVER 6
-#define DHCP_OPTION_HOSTNAME 12
-#define DHCP_OPTION_IP_TTL 23
-#define DHCP_OPTION_MTU 26
-#define DHCP_OPTION_BROADCAST 28
-#define DHCP_OPTION_TCP_TTL 37
-#define DHCP_OPTION_END 255
-
-/** DHCP options */
-#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */
-#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */
-#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */
-
-#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */
-#define DHCP_OPTION_MESSAGE_TYPE_LEN 1
-
-
-#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */
-#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */
-
-#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */
-#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2
-
-#define DHCP_OPTION_T1 58 /* T1 renewal time */
-#define DHCP_OPTION_T2 59 /* T2 rebinding time */
-#define DHCP_OPTION_US 60
-#define DHCP_OPTION_CLIENT_ID 61
-#define DHCP_OPTION_TFTP_SERVERNAME 66
-#define DHCP_OPTION_BOOTFILE 67
-
-/** possible combinations of overloading the file and sname fields with options */
-#define DHCP_OVERLOAD_NONE 0
-#define DHCP_OVERLOAD_FILE 1
-#define DHCP_OVERLOAD_SNAME 2
-#define DHCP_OVERLOAD_SNAME_FILE 3
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_DHCP */
-
-#endif /*__LWIP_DHCP_H__*/
+++ /dev/null
-/**
- * lwip DNS resolver header file.
-
- * Author: Jim Pettinato
- * April 2007
-
- * ported from uIP resolv.c Copyright (c) 2002-2003, Adam Dunkels.
- *
- * 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.
- */
-
-#ifndef __LWIP_DNS_H__
-#define __LWIP_DNS_H__
-
-#include "lwip/opt.h"
-
-#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
-
-/** DNS timer period */
-#define DNS_TMR_INTERVAL 1000
-
-/** DNS field TYPE used for "Resource Records" */
-#define DNS_RRTYPE_A 1 /* a host address */
-#define DNS_RRTYPE_NS 2 /* an authoritative name server */
-#define DNS_RRTYPE_MD 3 /* a mail destination (Obsolete - use MX) */
-#define DNS_RRTYPE_MF 4 /* a mail forwarder (Obsolete - use MX) */
-#define DNS_RRTYPE_CNAME 5 /* the canonical name for an alias */
-#define DNS_RRTYPE_SOA 6 /* marks the start of a zone of authority */
-#define DNS_RRTYPE_MB 7 /* a mailbox domain name (EXPERIMENTAL) */
-#define DNS_RRTYPE_MG 8 /* a mail group member (EXPERIMENTAL) */
-#define DNS_RRTYPE_MR 9 /* a mail rename domain name (EXPERIMENTAL) */
-#define DNS_RRTYPE_NULL 10 /* a null RR (EXPERIMENTAL) */
-#define DNS_RRTYPE_WKS 11 /* a well known service description */
-#define DNS_RRTYPE_PTR 12 /* a domain name pointer */
-#define DNS_RRTYPE_HINFO 13 /* host information */
-#define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information */
-#define DNS_RRTYPE_MX 15 /* mail exchange */
-#define DNS_RRTYPE_TXT 16 /* text strings */
-
-/** DNS field CLASS used for "Resource Records" */
-#define DNS_RRCLASS_IN 1 /* the Internet */
-#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */
-#define DNS_RRCLASS_CH 3 /* the CHAOS class */
-#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */
-#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */
-
-/** Callback which is invoked when a hostname is found.
- * A function of this type must be implemented by the application using the DNS resolver.
- * @param name pointer to the name that was looked up.
- * @param ipaddr pointer to a struct ip_addr containing the IP address of the hostname,
- * or NULL if the name could not be found (or on any other error).
- * @param callback_arg a user-specified callback argument passed to dns_gethostbyname
-*/
-typedef void (*dns_found_callback)(const char *name, struct ip_addr *ipaddr, void *callback_arg);
-
-
-void dns_init(void);
-
-void dns_tmr(void);
-
-void dns_setserver(u8_t numdns, struct ip_addr *dnsserver);
-
-struct ip_addr dns_getserver(u8_t numdns);
-
-err_t dns_gethostbyname(const char *hostname, struct ip_addr *addr,
- dns_found_callback found, void *callback_arg);
-
-#endif /* LWIP_DNS */
-
-#endif /* __LWIP_DNS_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_INIT_H__
-#define __LWIP_INIT_H__
-
-#include "lwip/opt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Modules initialization */
-void lwip_init(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_INIT_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_MEM_H__
-#define __LWIP_MEM_H__
-
-#include "lwip/opt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if MEM_LIBC_MALLOC
-
-#include <stddef.h> /* for size_t */
-
-typedef size_t mem_size_t;
-
-/* aliases for C library malloc() */
-#define mem_init()
-/* in case C library malloc() needs extra protection,
- * allow these defines to be overridden.
- */
-#ifndef mem_free
-#define mem_free(x) free(x)
-#endif
-#ifndef mem_malloc
-#define mem_malloc(x) malloc(x)
-#endif
-#ifndef mem_calloc
-#define mem_calloc(x, y) calloc(x, y)
-#endif
-#ifndef mem_realloc
-#define mem_realloc(x, size) (x)
-#endif
-#else /* MEM_LIBC_MALLOC */
-
-/* MEM_SIZE would have to be aligned, but using 64000 here instead of
- * 65535 leaves some room for alignment...
- */
-#if MEM_SIZE > 64000l
-typedef u32_t mem_size_t;
-#else
-typedef u16_t mem_size_t;
-#endif /* MEM_SIZE > 64000 */
-
-#if MEM_USE_POOLS
-/** mem_init is not used when using pools instead of a heap */
-#define mem_init()
-/** mem_realloc is not used when using pools instead of a heap:
- we can't free part of a pool element and don't want to copy the rest */
-#define mem_realloc(mem, size) (mem)
-#else /* MEM_USE_POOLS */
-/* lwIP alternative malloc */
-void mem_init(void);
-void *mem_realloc(void *mem, mem_size_t size);
-#endif /* MEM_USE_POOLS */
-void *mem_malloc(mem_size_t size);
-void *mem_calloc(mem_size_t count, mem_size_t size);
-void mem_free(void *mem);
-#endif /* MEM_LIBC_MALLOC */
-
-#ifndef LWIP_MEM_ALIGN_SIZE
-#define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1))
-#endif
-
-#ifndef LWIP_MEM_ALIGN
-#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1)))
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_MEM_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-#ifndef __LWIP_MEMP_H__
-#define __LWIP_MEMP_H__
-
-#include "lwip/opt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Create the list of all memory pools managed by memp. MEMP_MAX represents a NULL pool at the end */
-typedef enum {
-#define LWIP_MEMPOOL(name,num,size,desc) MEMP_##name,
-#include "lwip/memp_std.h"
- MEMP_MAX
-} memp_t;
-
-#if MEM_USE_POOLS
-/* Use a helper type to get the start and end of the user "memory pools" for mem_malloc */
-typedef enum {
- /* Get the first (via:
- MEMP_POOL_HELPER_START = ((u8_t) 1*MEMP_POOL_A + 0*MEMP_POOL_B + 0*MEMP_POOL_C + 0)*/
- MEMP_POOL_HELPER_FIRST = ((u8_t)
-#define LWIP_MEMPOOL(name,num,size,desc)
-#define LWIP_MALLOC_MEMPOOL_START 1
-#define LWIP_MALLOC_MEMPOOL(num, size) * MEMP_POOL_##size + 0
-#define LWIP_MALLOC_MEMPOOL_END
-#include "lwip/memp_std.h"
- ) ,
- /* Get the last (via:
- MEMP_POOL_HELPER_END = ((u8_t) 0 + MEMP_POOL_A*0 + MEMP_POOL_B*0 + MEMP_POOL_C*1) */
- MEMP_POOL_HELPER_LAST = ((u8_t)
-#define LWIP_MEMPOOL(name,num,size,desc)
-#define LWIP_MALLOC_MEMPOOL_START
-#define LWIP_MALLOC_MEMPOOL(num, size) 0 + MEMP_POOL_##size *
-#define LWIP_MALLOC_MEMPOOL_END 1
-#include "lwip/memp_std.h"
- )
-} memp_pool_helper_t;
-
-/* The actual start and stop values are here (cast them over)
- We use this helper type and these defines so we can avoid using const memp_t values */
-#define MEMP_POOL_FIRST ((memp_t) MEMP_POOL_HELPER_FIRST)
-#define MEMP_POOL_LAST ((memp_t) MEMP_POOL_HELPER_LAST)
-
-extern const u16_t memp_sizes[MEMP_MAX];
-#endif /* MEM_USE_POOLS */
-
-void memp_init(void);
-
-#if MEMP_OVERFLOW_CHECK
-void *memp_malloc_fn(memp_t type, const char* file, const int line);
-#define memp_malloc(t) memp_malloc_fn((t), __FILE__, __LINE__)
-#else
-void *memp_malloc(memp_t type);
-#endif
-void memp_free(memp_t type, void *mem);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_MEMP_H__ */
+++ /dev/null
-/*
- * SETUP: Make sure we define everything we will need.
- *
- * We have create three types of pools:
- * 1) MEMPOOL - standard pools
- * 2) MALLOC_MEMPOOL - to be used by mem_malloc in mem.c
- * 3) PBUF_MEMPOOL - a mempool of pbuf's, so include space for the pbuf struct
- *
- * If the include'r doesn't require any special treatment of each of the types
- * above, then will declare #2 & #3 to be just standard mempools.
- */
-#ifndef LWIP_MALLOC_MEMPOOL
-/* This treats "malloc pools" just like any other pool */
-#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, size, "MALLOC_"#size)
-#define LWIP_MALLOC_MEMPOOL_START
-#define LWIP_MALLOC_MEMPOOL_END
-#endif /* LWIP_MALLOC_MEMPOOL */
-
-#ifndef LWIP_PBUF_MEMPOOL
-/* This treats "pbuf pools" just like any other pool.
- * Allocates buffers for a pbuf struct AND a payload size */
-#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, (MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(payload)), desc)
-#endif /* LWIP_PBUF_MEMPOOL */
-
-
-/*
- * A list of internal pools used by LWIP.
- *
- * LWIP_MEMPOOL(pool_name, number_elements, element_size, pool_description)
- * creates a pool name MEMP_pool_name. description is used in stats.c
- */
-#if LWIP_RAW
-LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB")
-#endif /* LWIP_RAW */
-
-#if LWIP_UDP
-LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB")
-#endif /* LWIP_UDP */
-
-#if LWIP_TCP
-LWIP_MEMPOOL(TCP_PCB, MEMP_NUM_TCP_PCB, sizeof(struct tcp_pcb), "TCP_PCB")
-LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN, sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN")
-LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg), "TCP_SEG")
-#endif /* LWIP_TCP */
-
-#if IP_REASSEMBLY
-LWIP_MEMPOOL(REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip_reassdata), "REASSDATA")
-#endif /* IP_REASSEMBLY */
-
-#if LWIP_NETCONN
-LWIP_MEMPOOL(NETBUF, MEMP_NUM_NETBUF, sizeof(struct netbuf), "NETBUF")
-LWIP_MEMPOOL(NETCONN, MEMP_NUM_NETCONN, sizeof(struct netconn), "NETCONN")
-#endif /* LWIP_NETCONN */
-
-#if NO_SYS==0
-LWIP_MEMPOOL(TCPIP_MSG_API, MEMP_NUM_TCPIP_MSG_API, sizeof(struct tcpip_msg), "TCPIP_MSG_API")
-LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg), "TCPIP_MSG_INPKT")
-#endif /* NO_SYS==0 */
-
-#if ARP_QUEUEING
-LWIP_MEMPOOL(ARP_QUEUE, MEMP_NUM_ARP_QUEUE, sizeof(struct etharp_q_entry), "ARP_QUEUE")
-#endif /* ARP_QUEUEING */
-
-#if LWIP_IGMP
-LWIP_MEMPOOL(IGMP_GROUP, MEMP_NUM_IGMP_GROUP, sizeof(struct igmp_group), "IGMP_GROUP")
-#endif /* LWIP_IGMP */
-
-#if NO_SYS==0
-LWIP_MEMPOOL(SYS_TIMEOUT, MEMP_NUM_SYS_TIMEOUT, sizeof(struct sys_timeo), "SYS_TIMEOUT")
-#endif /* NO_SYS==0 */
-
-
-/*
- * A list of pools of pbuf's used by LWIP.
- *
- * LWIP_PBUF_MEMPOOL(pool_name, number_elements, pbuf_payload_size, pool_description)
- * creates a pool name MEMP_pool_name. description is used in stats.c
- * This allocates enough space for the pbuf struct and a payload.
- * (Example: pbuf_payload_size=0 allocates only size for the struct)
- */
-LWIP_PBUF_MEMPOOL(PBUF, MEMP_NUM_PBUF, 0, "PBUF_REF/ROM")
-LWIP_PBUF_MEMPOOL(PBUF_POOL, PBUF_POOL_SIZE, PBUF_POOL_BUFSIZE, "PBUF_POOL")
-
-
-/*
- * Allow for user-defined pools; this must be explicitly set in lwipopts.h
- * since the default is to NOT look for lwippools.h
- */
-#if MEMP_USE_CUSTOM_POOLS
-#include "lwippools.h"
-#endif /* MEMP_USE_CUSTOM_POOLS */
-
-/*
- * REQUIRED CLEANUP: Clear up so we don't get "multiply defined" error later
- * (#undef is ignored for something that is not defined)
- */
-#undef LWIP_MEMPOOL
-#undef LWIP_MALLOC_MEMPOOL
-#undef LWIP_MALLOC_MEMPOOL_START
-#undef LWIP_MALLOC_MEMPOOL_END
-#undef LWIP_PBUF_MEMPOOL
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_NETBUF_H__
-#define __LWIP_NETBUF_H__
-
-#include "lwip/opt.h"
-#include "lwip/pbuf.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct netbuf {
- struct pbuf *p, *ptr;
- struct ip_addr *addr;
- u16_t port;
-};
-
-/* Network buffer functions: */
-struct netbuf * netbuf_new (void);
-void netbuf_delete (struct netbuf *buf);
-void * netbuf_alloc (struct netbuf *buf, u16_t size);
-void netbuf_free (struct netbuf *buf);
-err_t netbuf_ref (struct netbuf *buf,
- const void *dataptr, u16_t size);
-void netbuf_chain (struct netbuf *head,
- struct netbuf *tail);
-
-u16_t netbuf_len (struct netbuf *buf);
-err_t netbuf_data (struct netbuf *buf,
- void **dataptr, u16_t *len);
-s8_t netbuf_next (struct netbuf *buf);
-void netbuf_first (struct netbuf *buf);
-
-
-#define netbuf_copy_partial(buf, dataptr, len, offset) \
- pbuf_copy_partial((buf)->p, (dataptr), (len), (offset))
-#define netbuf_copy(buf,dataptr,len) netbuf_copy_partial(buf, dataptr, len, 0)
-#define netbuf_len(buf) ((buf)->p->tot_len)
-#define netbuf_fromaddr(buf) ((buf)->addr)
-#define netbuf_fromport(buf) ((buf)->port)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_NETBUF_H__ */
+++ /dev/null
-/*
- * 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.
- *
- * Author: Simon Goldschmidt
- *
- */
-
-#include "lwip/opt.h"
-
-#if LWIP_DNS && LWIP_SOCKET
-
-#include "lwip/sockets.h"
-
-/* some rarely used options */
-#ifndef LWIP_DNS_API_DECLARE_H_ERRNO
-#define LWIP_DNS_API_DECLARE_H_ERRNO 1
-#endif
-
-#ifndef LWIP_DNS_API_DEFINE_ERRORS
-#define LWIP_DNS_API_DEFINE_ERRORS 1
-#endif
-
-#ifndef LWIP_DNS_API_DECLARE_STRUCTS
-#define LWIP_DNS_API_DECLARE_STRUCTS 1
-#endif
-
-#if LWIP_DNS_API_DEFINE_ERRORS
-/** Errors used by the DNS API functions, h_errno can be one of them */
-#define EAI_NONAME 200
-#define EAI_SERVICE 201
-#define EAI_FAIL 202
-#define EAI_MEMORY 203
-
-#define HOST_NOT_FOUND 210
-#define NO_DATA 211
-#define NO_RECOVERY 212
-#define TRY_AGAIN 213
-#endif /* LWIP_DNS_API_DEFINE_ERRORS */
-
-#if LWIP_DNS_API_DECLARE_STRUCTS
-struct hostent {
- char *h_name; /* Official name of the host. */
- char **h_aliases; /* A pointer to an array of pointers to alternative host names,
- terminated by a null pointer. */
- int h_addrtype; /* Address type. */
- int h_length; /* The length, in bytes, of the address. */
- char **h_addr_list; /* A pointer to an array of pointers to network addresses (in
- network byte order) for the host, terminated by a null pointer. */
-#define h_addr h_addr_list[0] /* for backward compatibility */
-};
-
-struct addrinfo {
- int ai_flags; /* Input flags. */
- int ai_family; /* Address family of socket. */
- int ai_socktype; /* Socket type. */
- int ai_protocol; /* Protocol of socket. */
- socklen_t ai_addrlen; /* Length of socket address. */
- struct sockaddr *ai_addr; /* Socket address of socket. */
- char *ai_canonname; /* Canonical name of service location. */
- struct addrinfo *ai_next; /* Pointer to next in list. */
-};
-#endif /* LWIP_DNS_API_DECLARE_STRUCTS */
-
-#if LWIP_DNS_API_DECLARE_H_ERRNO
-/* application accessable error code set by the DNS API functions */
-extern int h_errno;
-#endif /* LWIP_DNS_API_DECLARE_H_ERRNO*/
-
-struct hostent *lwip_gethostbyname(const char *name);
-int lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
- size_t buflen, struct hostent **result, int *h_errnop);
-void lwip_freeaddrinfo(struct addrinfo *ai);
-int lwip_getaddrinfo(const char *nodename,
- const char *servname,
- const struct addrinfo *hints,
- struct addrinfo **res);
-
-#if LWIP_COMPAT_SOCKETS
-#define gethostbyname(name) lwip_gethostbyname(name)
-#define gethostbyname_r(name, ret, buf, buflen, result, h_errnop) \
- lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop)
-#define freeaddrinfo(addrinfo) lwip_freeaddrinfo(a)
-#define getaddrinfo(nodname, servname, hints, res) \
- lwip_getaddrinfo(nodname, servname, hints, res)
-#endif /* LWIP_COMPAT_SOCKETS */
-
-#endif /* LWIP_DNS && LWIP_SOCKET */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_NETIF_H__
-#define __LWIP_NETIF_H__
-
-#include "lwip/opt.h"
-
-#include "lwip/err.h"
-
-#include "lwip/ip_addr.h"
-
-#include "lwip/inet.h"
-#include "lwip/pbuf.h"
-#if LWIP_DHCP
-struct dhcp;
-#endif
-#if LWIP_AUTOIP
-struct autoip;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Throughout this file, IP addresses are expected to be in
- * the same byte order as in IP_PCB. */
-
-/** must be the maximum of all used hardware address lengths
- across all types of interfaces in use */
-#define NETIF_MAX_HWADDR_LEN 6U
-
-/** TODO: define the use (where, when, whom) of netif flags */
-
-/** whether the network interface is 'up'. this is
- * a software flag used to control whether this network
- * interface is enabled and processes traffic.
- */
-#define NETIF_FLAG_UP 0x01U
-/** if set, the netif has broadcast capability */
-#define NETIF_FLAG_BROADCAST 0x02U
-/** if set, the netif is one end of a point-to-point connection */
-#define NETIF_FLAG_POINTTOPOINT 0x04U
-/** if set, the interface is configured using DHCP */
-#define NETIF_FLAG_DHCP 0x08U
-/** if set, the interface has an active link
- * (set by the network interface driver) */
-#define NETIF_FLAG_LINK_UP 0x10U
-/** if set, the netif is an device using ARP */
-#define NETIF_FLAG_ETHARP 0x20U
-/** if set, the netif has IGMP capability */
-#define NETIF_FLAG_IGMP 0x40U
-
-/** Generic data structure used for all lwIP network interfaces.
- * The following fields should be filled in by the initialization
- * function for the device driver: hwaddr_len, hwaddr[], mtu, flags */
-
-struct netif {
- /** pointer to next in linked list */
- struct netif *next;
-
- /** IP address configuration in network byte order */
- struct ip_addr ip_addr;
- struct ip_addr netmask;
- struct ip_addr gw;
-
- /** This function is called by the network device driver
- * to pass a packet up the TCP/IP stack. */
- err_t (* input)(struct pbuf *p, struct netif *inp);
- /** This function is called by the IP module when it wants
- * to send a packet on the interface. This function typically
- * first resolves the hardware address, then sends the packet. */
- err_t (* output)(struct netif *netif, struct pbuf *p,
- struct ip_addr *ipaddr);
- /** This function is called by the ARP module when it wants
- * to send a packet on the interface. This function outputs
- * the pbuf as-is on the link medium. */
- err_t (* linkoutput)(struct netif *netif, struct pbuf *p);
-#if LWIP_NETIF_STATUS_CALLBACK
- /** This function is called when the netif state is set to up or down
- */
- void (* status_callback)(struct netif *netif);
-#endif /* LWIP_NETIF_STATUS_CALLBACK */
-#if LWIP_NETIF_LINK_CALLBACK
- /** This function is called when the netif link is set to up or down
- */
- void (* link_callback)(struct netif *netif);
-#endif /* LWIP_NETIF_LINK_CALLBACK */
- /** This field can be set by the device driver and could point
- * to state information for the device. */
- void *state;
-#if LWIP_DHCP
- /** the DHCP client state information for this netif */
- struct dhcp *dhcp;
-#endif /* LWIP_DHCP */
-#if LWIP_AUTOIP
- /** the AutoIP client state information for this netif */
- struct autoip *autoip;
-#endif
-#if LWIP_NETIF_HOSTNAME
- /* the hostname for this netif, NULL is a valid value */
- char* hostname;
-#endif /* LWIP_NETIF_HOSTNAME */
- /** number of bytes used in hwaddr */
- u8_t hwaddr_len;
- /** link level hardware address of this interface */
- u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
- /** maximum transfer unit (in bytes) */
- u16_t mtu;
- /** flags (see NETIF_FLAG_ above) */
- u8_t flags;
- /** descriptive abbreviation */
- char name[2];
- /** number of this interface */
- u8_t num;
-#if LWIP_SNMP
- /** link type (from "snmp_ifType" enum from snmp.h) */
- u8_t link_type;
- /** (estimate) link speed */
- u32_t link_speed;
- /** timestamp at last change made (up/down) */
- u32_t ts;
- /** counters */
- u32_t ifinoctets;
- u32_t ifinucastpkts;
- u32_t ifinnucastpkts;
- u32_t ifindiscards;
- u32_t ifoutoctets;
- u32_t ifoutucastpkts;
- u32_t ifoutnucastpkts;
- u32_t ifoutdiscards;
-#endif /* LWIP_SNMP */
-#if LWIP_IGMP
- /* This function could be called to add or delete a entry in the multicast filter table of the ethernet MAC.*/
- err_t (*igmp_mac_filter)( struct netif *netif, struct ip_addr *group, u8_t action);
-#endif /* LWIP_IGMP */
-#if LWIP_NETIF_HWADDRHINT
- u8_t *addr_hint;
-#endif /* LWIP_NETIF_HWADDRHINT */
-};
-
-#if LWIP_SNMP
-#define NETIF_INIT_SNMP(netif, type, speed) \
- /* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \
- netif->link_type = type; \
- /* your link speed here (units: bits per second) */ \
- netif->link_speed = speed; \
- netif->ts = 0; \
- netif->ifinoctets = 0; \
- netif->ifinucastpkts = 0; \
- netif->ifinnucastpkts = 0; \
- netif->ifindiscards = 0; \
- netif->ifoutoctets = 0; \
- netif->ifoutucastpkts = 0; \
- netif->ifoutnucastpkts = 0; \
- netif->ifoutdiscards = 0
-#else /* LWIP_SNMP */
-#define NETIF_INIT_SNMP(netif, type, speed)
-#endif /* LWIP_SNMP */
-
-
-/** The list of network interfaces. */
-extern struct netif *netif_list;
-/** The default network interface. */
-extern struct netif *netif_default;
-
-#define netif_init() /* Compatibility define, not init needed. */
-
-struct netif *netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
- struct ip_addr *gw,
- void *state,
- err_t (* init)(struct netif *netif),
- err_t (* input)(struct pbuf *p, struct netif *netif));
-
-void
-netif_set_addr(struct netif *netif,struct ip_addr *ipaddr, struct ip_addr *netmask,
- struct ip_addr *gw);
-void netif_remove(struct netif * netif);
-
-/* Returns a network interface given its name. The name is of the form
- "et0", where the first two letters are the "name" field in the
- netif structure, and the digit is in the num field in the same
- structure. */
-struct netif *netif_find(char *name);
-
-void netif_set_default(struct netif *netif);
-
-void netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr);
-void netif_set_netmask(struct netif *netif, struct ip_addr *netmask);
-void netif_set_gw(struct netif *netif, struct ip_addr *gw);
-
-void netif_set_up(struct netif *netif);
-void netif_set_down(struct netif *netif);
-u8_t netif_is_up(struct netif *netif);
-
-#if LWIP_NETIF_STATUS_CALLBACK
-/*
- * Set callback to be called when interface is brought up/down
- */
-void netif_set_status_callback(struct netif *netif, void (* status_callback)(struct netif *netif));
-#endif /* LWIP_NETIF_STATUS_CALLBACK */
-
-#if LWIP_NETIF_LINK_CALLBACK
-void netif_set_link_up(struct netif *netif);
-void netif_set_link_down(struct netif *netif);
-u8_t netif_is_link_up(struct netif *netif);
-/*
- * Set callback to be called when link is brought up/down
- */
-void netif_set_link_callback(struct netif *netif, void (* link_callback)(struct netif *netif));
-#endif /* LWIP_NETIF_LINK_CALLBACK */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_NETIF_H__ */
+++ /dev/null
-/*
- * 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.
- *
- */
-
-#ifndef __LWIP_NETIFAPI_H__
-#define __LWIP_NETIFAPI_H__
-
-#include "lwip/opt.h"
-
-#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/sys.h"
-#include "lwip/netif.h"
-#include "lwip/dhcp.h"
-#include "lwip/autoip.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct netifapi_msg_msg {
-#if !LWIP_TCPIP_CORE_LOCKING
- sys_sem_t sem;
-#endif /* !LWIP_TCPIP_CORE_LOCKING */
- err_t err;
- struct netif *netif;
- union {
- struct {
- struct ip_addr *ipaddr;
- struct ip_addr *netmask;
- struct ip_addr *gw;
- void *state;
- err_t (* init) (struct netif *netif);
- err_t (* input)(struct pbuf *p, struct netif *netif);
- } add;
- struct {
- void (* voidfunc)(struct netif *netif);
- err_t (* errtfunc)(struct netif *netif);
- } common;
- } msg;
-};
-
-struct netifapi_msg {
- void (* function)(struct netifapi_msg_msg *msg);
- struct netifapi_msg_msg msg;
-};
-
-
-/* API for application */
-err_t netifapi_netif_add ( struct netif *netif,
- struct ip_addr *ipaddr,
- struct ip_addr *netmask,
- struct ip_addr *gw,
- void *state,
- err_t (* init)(struct netif *netif),
- err_t (* input)(struct pbuf *p, struct netif *netif) );
-
-err_t netifapi_netif_common ( struct netif *netif,
- void (* voidfunc)(struct netif *netif),
- err_t (* errtfunc)(struct netif *netif) );
-
-#define netifapi_netif_remove(n) netifapi_netif_common(n, netif_remove, NULL)
-#define netifapi_netif_set_up(n) netifapi_netif_common(n, netif_set_up, NULL)
-#define netifapi_netif_set_down(n) netifapi_netif_common(n, netif_set_down, NULL)
-#define netifapi_netif_set_default(n) netifapi_netif_common(n, netif_set_default, NULL)
-#define netifapi_dhcp_start(n) netifapi_netif_common(n, NULL, dhcp_start)
-#define netifapi_dhcp_stop(n) netifapi_netif_common(n, dhcp_stop, NULL)
-#define netifapi_autoip_start(n) netifapi_netif_common(n, NULL, autoip_start)
-#define netifapi_autoip_stop(n) netifapi_netif_common(n, NULL, autoip_stop)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_NETIF_API */
-
-#endif /* __LWIP_NETIFAPI_H__ */
+++ /dev/null
-/**
- * @file
- *
- * lwIP Options Configuration
- */
-
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_OPT_H__
-#define __LWIP_OPT_H__
-
-/*
- * Include user defined options first. Anything not defined in these files
- * will be set to standard values. Override anything you dont like!
- */
-#include "lwipopts.h"
-#include "lwip/debug.h"
-
-/*
- -----------------------------------------------
- ---------- Platform specific locking ----------
- -----------------------------------------------
-*/
-
-/**
- * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
- * critical regions during buffer allocation, deallocation and memory
- * allocation and deallocation.
- */
-#ifndef SYS_LIGHTWEIGHT_PROT
-#define SYS_LIGHTWEIGHT_PROT 0
-#endif
-
-/**
- * NO_SYS==1: Provides VERY minimal functionality. Otherwise,
- * use lwIP facilities.
- */
-#ifndef NO_SYS
-#define NO_SYS 0
-#endif
-
-/**
- * MEMCPY: override this if you have a faster implementation at hand than the
- * one included in your C library
- */
-#ifndef MEMCPY
-#define MEMCPY(dst,src,len) memcpy(dst,src,len)
-#endif
-
-/**
- * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a
- * call to memcpy() if the length is known at compile time and is small.
- */
-#ifndef SMEMCPY
-#define SMEMCPY(dst,src,len) memcpy(dst,src,len)
-#endif
-
-/*
- ------------------------------------
- ---------- Memory options ----------
- ------------------------------------
-*/
-/**
- * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library
- * instead of the lwip internal allocator. Can save code size if you
- * already use it.
- */
-#ifndef MEM_LIBC_MALLOC
-#define MEM_LIBC_MALLOC 0
-#endif
-
-/**
- * MEM_ALIGNMENT: should be set to the alignment of the CPU
- * 4 byte alignment -> #define MEM_ALIGNMENT 4
- * 2 byte alignment -> #define MEM_ALIGNMENT 2
- */
-#ifndef MEM_ALIGNMENT
-#define MEM_ALIGNMENT 1
-#endif
-
-/**
- * MEM_SIZE: the size of the heap memory. If the application will send
- * a lot of data that needs to be copied, this should be set high.
- */
-#ifndef MEM_SIZE
-#define MEM_SIZE 1600
-#endif
-
-/**
- * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable
- * amount of bytes before and after each memp element in every pool and fills
- * it with a prominent default value.
- * MEMP_OVERFLOW_CHECK == 0 no checking
- * MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed
- * MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time
- * memp_malloc() or memp_free() is called (useful but slow!)
- */
-#ifndef MEMP_OVERFLOW_CHECK
-#define MEMP_OVERFLOW_CHECK 0
-#endif
-
-/**
- * MEMP_SANITY_CHECK==1: run a sanity check after each memp_free() to make
- * sure that there are no cycles in the linked lists.
- */
-#ifndef MEMP_SANITY_CHECK
-#define MEMP_SANITY_CHECK 0
-#endif
-
-/**
- * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set
- * of memory pools of various sizes. When mem_malloc is called, an element of
- * the smallest pool that can provide the lenght needed is returned.
- */
-#ifndef MEM_USE_POOLS
-#define MEM_USE_POOLS 0
-#endif
-
-/**
- * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h
- * that defines additional pools beyond the "standard" ones required
- * by lwIP. If you set this to 1, you must have lwippools.h in your
- * inlude path somewhere.
- */
-#ifndef MEMP_USE_CUSTOM_POOLS
-#define MEMP_USE_CUSTOM_POOLS 0
-#endif
-
-
-/*
- ------------------------------------------------
- ---------- Internal Memory Pool Sizes ----------
- ------------------------------------------------
-*/
-/**
- * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF).
- * If the application sends a lot of data out of ROM (or other static memory),
- * this should be set high.
- */
-#ifndef MEMP_NUM_PBUF
-#define MEMP_NUM_PBUF 16
-#endif
-
-/**
- * MEMP_NUM_RAW_PCB: Number of raw connection PCBs
- * (requires the LWIP_RAW option)
- */
-#ifndef MEMP_NUM_RAW_PCB
-#define MEMP_NUM_RAW_PCB 4
-#endif
-
-/**
- * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
- * per active UDP "connection".
- * (requires the LWIP_UDP option)
- */
-#ifndef MEMP_NUM_UDP_PCB
-#define MEMP_NUM_UDP_PCB 4
-#endif
-
-/**
- * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections.
- * (requires the LWIP_TCP option)
- */
-#ifndef MEMP_NUM_TCP_PCB
-#define MEMP_NUM_TCP_PCB 5
-#endif
-
-/**
- * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections.
- * (requires the LWIP_TCP option)
- */
-#ifndef MEMP_NUM_TCP_PCB_LISTEN
-#define MEMP_NUM_TCP_PCB_LISTEN 8
-#endif
-
-/**
- * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments.
- * (requires the LWIP_TCP option)
- */
-#ifndef MEMP_NUM_TCP_SEG
-#define MEMP_NUM_TCP_SEG 16
-#endif
-
-/**
- * MEMP_NUM_REASSDATA: the number of simultaneously IP packets queued for
- * reassembly (whole packets, not fragments!)
- */
-#ifndef MEMP_NUM_REASSDATA
-#define MEMP_NUM_REASSDATA 5
-#endif
-
-/**
- * MEMP_NUM_ARP_QUEUE: the number of simulateously queued outgoing
- * packets (pbufs) that are waiting for an ARP request (to resolve
- * their destination address) to finish.
- * (requires the ARP_QUEUEING option)
- */
-#ifndef MEMP_NUM_ARP_QUEUE
-#define MEMP_NUM_ARP_QUEUE 30
-#endif
-
-/**
- * MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces
- * can be members et the same time (one per netif - allsystems group -, plus one
- * per netif membership).
- * (requires the LWIP_IGMP option)
- */
-#ifndef MEMP_NUM_IGMP_GROUP
-#define MEMP_NUM_IGMP_GROUP 8
-#endif
-
-/**
- * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts.
- * (requires NO_SYS==0)
- */
-#ifndef MEMP_NUM_SYS_TIMEOUT
-#define MEMP_NUM_SYS_TIMEOUT 3
-#endif
-
-/**
- * MEMP_NUM_NETBUF: the number of struct netbufs.
- * (only needed if you use the sequential API, like api_lib.c)
- */
-#ifndef MEMP_NUM_NETBUF
-#define MEMP_NUM_NETBUF 2
-#endif
-
-/**
- * MEMP_NUM_NETCONN: the number of struct netconns.
- * (only needed if you use the sequential API, like api_lib.c)
- */
-#ifndef MEMP_NUM_NETCONN
-#define MEMP_NUM_NETCONN 4
-#endif
-
-/**
- * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used
- * for callback/timeout API communication.
- * (only needed if you use tcpip.c)
- */
-#ifndef MEMP_NUM_TCPIP_MSG_API
-#define MEMP_NUM_TCPIP_MSG_API 8
-#endif
-
-/**
- * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used
- * for incoming packets.
- * (only needed if you use tcpip.c)
- */
-#ifndef MEMP_NUM_TCPIP_MSG_INPKT
-#define MEMP_NUM_TCPIP_MSG_INPKT 8
-#endif
-
-/**
- * PBUF_POOL_SIZE: the number of buffers in the pbuf pool.
- */
-#ifndef PBUF_POOL_SIZE
-#define PBUF_POOL_SIZE 16
-#endif
-
-/*
- ---------------------------------
- ---------- ARP options ----------
- ---------------------------------
-*/
-/**
- * LWIP_ARP==1: Enable ARP functionality.
- */
-#ifndef LWIP_ARP
-#define LWIP_ARP 1
-#endif
-
-/**
- * ARP_TABLE_SIZE: Number of active MAC-IP address pairs cached.
- */
-#ifndef ARP_TABLE_SIZE
-#define ARP_TABLE_SIZE 10
-#endif
-
-/**
- * ARP_QUEUEING==1: Outgoing packets are queued during hardware address
- * resolution.
- */
-#ifndef ARP_QUEUEING
-#define ARP_QUEUEING 1
-#endif
-
-/**
- * ETHARP_TRUST_IP_MAC==1: Incoming IP packets cause the ARP table to be
- * updated with the source MAC and IP addresses supplied in the packet.
- * You may want to disable this if you do not trust LAN peers to have the
- * correct addresses, or as a limited approach to attempt to handle
- * spoofing. If disabled, lwIP will need to make a new ARP request if
- * the peer is not already in the ARP table, adding a little latency.
- */
-#ifndef ETHARP_TRUST_IP_MAC
-#define ETHARP_TRUST_IP_MAC 1
-#endif
-
-/*
- --------------------------------
- ---------- IP options ----------
- --------------------------------
-*/
-/**
- * IP_FORWARD==1: Enables the ability to forward IP packets across network
- * interfaces. If you are going to run lwIP on a device with only one network
- * interface, define this to 0.
- */
-#ifndef IP_FORWARD
-#define IP_FORWARD 0
-#endif
-
-/**
- * IP_OPTIONS_ALLOWED: Defines the behavior for IP options.
- * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped.
- * IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed).
- */
-#ifndef IP_OPTIONS_ALLOWED
-#define IP_OPTIONS_ALLOWED 1
-#endif
-
-/**
- * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that
- * this option does not affect outgoing packet sizes, which can be controlled
- * via IP_FRAG.
- */
-#ifndef IP_REASSEMBLY
-#define IP_REASSEMBLY 1
-#endif
-
-/**
- * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note
- * that this option does not affect incoming packet sizes, which can be
- * controlled via IP_REASSEMBLY.
- */
-#ifndef IP_FRAG
-#define IP_FRAG 1
-#endif
-
-/**
- * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally)
- * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived
- * in this time, the whole packet is discarded.
- */
-#ifndef IP_REASS_MAXAGE
-#define IP_REASS_MAXAGE 3
-#endif
-
-/**
- * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled.
- * Since the received pbufs are enqueued, be sure to configure
- * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive
- * packets even if the maximum amount of fragments is enqueued for reassembly!
- */
-#ifndef IP_REASS_MAX_PBUFS
-#define IP_REASS_MAX_PBUFS 10
-#endif
-
-/**
- * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP
- * fragmentation. Otherwise pbufs are allocated and reference the original
- * packet data to be fragmented.
- */
-#ifndef IP_FRAG_USES_STATIC_BUF
-#define IP_FRAG_USES_STATIC_BUF 1
-#endif
-
-/**
- * IP_FRAG_MAX_MTU: Assumed max MTU on any interface for IP frag buffer
- * (requires IP_FRAG_USES_STATIC_BUF==1)
- */
-#if IP_FRAG_USES_STATIC_BUF && !defined(IP_FRAG_MAX_MTU)
-#define IP_FRAG_MAX_MTU 1500
-#endif
-
-/**
- * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers.
- */
-#ifndef IP_DEFAULT_TTL
-#define IP_DEFAULT_TTL 255
-#endif
-
-/*
- ----------------------------------
- ---------- ICMP options ----------
- ----------------------------------
-*/
-/**
- * LWIP_ICMP==1: Enable ICMP module inside the IP stack.
- * Be careful, disable that make your product non-compliant to RFC1122
- */
-#ifndef LWIP_ICMP
-#define LWIP_ICMP 1
-#endif
-
-/**
- * ICMP_TTL: Default value for Time-To-Live used by ICMP packets.
- */
-#ifndef ICMP_TTL
-#define ICMP_TTL (IP_DEFAULT_TTL)
-#endif
-
-/*
- ---------------------------------
- ---------- RAW options ----------
- ---------------------------------
-*/
-/**
- * LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
- */
-#ifndef LWIP_RAW
-#define LWIP_RAW 1
-#endif
-
-/**
- * LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
- */
-#ifndef RAW_TTL
-#define RAW_TTL (IP_DEFAULT_TTL)
-#endif
-
-/*
- ----------------------------------
- ---------- DHCP options ----------
- ----------------------------------
-*/
-/**
- * LWIP_DHCP==1: Enable DHCP module.
- */
-#ifndef LWIP_DHCP
-#define LWIP_DHCP 0
-#endif
-
-/**
- * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address.
- */
-#ifndef DHCP_DOES_ARP_CHECK
-#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP))
-#endif
-
-/*
- ------------------------------------
- ---------- AUTOIP options ----------
- ------------------------------------
-*/
-/**
- * LWIP_AUTOIP==1: Enable AUTOIP module.
- */
-#ifndef LWIP_AUTOIP
-#define LWIP_AUTOIP 0
-#endif
-
-/**
- * LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on
- * the same interface at the same time.
- */
-#ifndef LWIP_DHCP_AUTOIP_COOP
-#define LWIP_DHCP_AUTOIP_COOP 0
-#endif
-
-/*
- ----------------------------------
- ---------- SNMP options ----------
- ----------------------------------
-*/
-/**
- * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP
- * transport.
- */
-#ifndef LWIP_SNMP
-#define LWIP_SNMP 0
-#endif
-
-/**
- * SNMP_CONCURRENT_REQUESTS: Number of concurrent requests the module will
- * allow. At least one request buffer is required.
- */
-#ifndef SNMP_CONCURRENT_REQUESTS
-#define SNMP_CONCURRENT_REQUESTS 1
-#endif
-
-/**
- * SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap
- * destination is required
- */
-#ifndef SNMP_TRAP_DESTINATIONS
-#define SNMP_TRAP_DESTINATIONS 1
-#endif
-
-/**
- * SNMP_PRIVATE_MIB:
- */
-#ifndef SNMP_PRIVATE_MIB
-#define SNMP_PRIVATE_MIB 0
-#endif
-
-/**
- * Only allow SNMP write actions that are 'safe' (e.g. disabeling netifs is not
- * a safe action and disabled when SNMP_SAFE_REQUESTS = 1).
- * Unsafe requests are disabled by default!
- */
-#ifndef SNMP_SAFE_REQUESTS
-#define SNMP_SAFE_REQUESTS 1
-#endif
-
-/*
- ----------------------------------
- ---------- IGMP options ----------
- ----------------------------------
-*/
-/**
- * LWIP_IGMP==1: Turn on IGMP module.
- */
-#ifndef LWIP_IGMP
-#define LWIP_IGMP 0
-#endif
-
-/*
- ----------------------------------
- ---------- DNS options -----------
- ----------------------------------
-*/
-/**
- * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS
- * transport.
- */
-#ifndef LWIP_DNS
-#define LWIP_DNS 0
-#endif
-
-/** DNS maximum number of entries to maintain locally. */
-#ifndef DNS_TABLE_SIZE
-#define DNS_TABLE_SIZE 4
-#endif
-
-/** DNS maximum host name length supported in the name table. */
-#ifndef DNS_MAX_NAME_LENGTH
-#define DNS_MAX_NAME_LENGTH 256
-#endif
-
-/** The maximum of DNS servers */
-#ifndef DNS_MAX_SERVERS
-#define DNS_MAX_SERVERS 2
-#endif
-
-/** DNS do a name checking between the query and the response. */
-#ifndef DNS_DOES_NAME_CHECK
-#define DNS_DOES_NAME_CHECK 1
-#endif
-
-/** DNS use a local buffer if DNS_USES_STATIC_BUF=0, a static one if
- DNS_USES_STATIC_BUF=1, or a dynamic one if DNS_USES_STATIC_BUF=2.
- The buffer will be of size DNS_MSG_SIZE */
-#ifndef DNS_USES_STATIC_BUF
-#define DNS_USES_STATIC_BUF 1
-#endif
-
-/** DNS message max. size. Default value is RFC compliant. */
-#ifndef DNS_MSG_SIZE
-#define DNS_MSG_SIZE 512
-#endif
-
-/*
- ---------------------------------
- ---------- UDP options ----------
- ---------------------------------
-*/
-/**
- * LWIP_UDP==1: Turn on UDP.
- */
-#ifndef LWIP_UDP
-#define LWIP_UDP 1
-#endif
-
-/**
- * LWIP_UDPLITE==1: Turn on UDP-Lite. (Requires LWIP_UDP)
- */
-#ifndef LWIP_UDPLITE
-#define LWIP_UDPLITE 0
-#endif
-
-/**
- * UDP_TTL: Default Time-To-Live value.
- */
-#ifndef UDP_TTL
-#define UDP_TTL (IP_DEFAULT_TTL)
-#endif
-
-/*
- ---------------------------------
- ---------- TCP options ----------
- ---------------------------------
-*/
-/**
- * LWIP_TCP==1: Turn on TCP.
- */
-#ifndef LWIP_TCP
-#define LWIP_TCP 1
-#endif
-
-/**
- * TCP_TTL: Default Time-To-Live value.
- */
-#ifndef TCP_TTL
-#define TCP_TTL (IP_DEFAULT_TTL)
-#endif
-
-/**
- * TCP_WND: The size of a TCP window.
- */
-#ifndef TCP_WND
-#define TCP_WND 2048
-#endif
-
-/**
- * TCP_MAXRTX: Maximum number of retransmissions of data segments.
- */
-#ifndef TCP_MAXRTX
-#define TCP_MAXRTX 12
-#endif
-
-/**
- * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments.
- */
-#ifndef TCP_SYNMAXRTX
-#define TCP_SYNMAXRTX 6
-#endif
-
-/**
- * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order.
- * Define to 0 if your device is low on memory.
- */
-#ifndef TCP_QUEUE_OOSEQ
-#define TCP_QUEUE_OOSEQ 1
-#endif
-
-/**
- * TCP_MSS: TCP Maximum segment size. (default is 128, a *very*
- * conservative default.)
- * For the receive side, this MSS is advertised to the remote side
- * when opening a connection. For the transmit size, this MSS sets
- * an upper limit on the MSS advertised by the remote host.
- */
-#ifndef TCP_MSS
-#define TCP_MSS 128
-#endif
-
-/**
- * TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really
- * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which
- * reflects the available reassembly buffer size at the remote host) and the
- * largest size permitted by the IP layer" (RFC 1122)
- * Setting this to 1 enables code that checks TCP_MSS against the MTU of the
- * netif used for a connection and limits the MSS if it would be too big otherwise.
- */
-#ifndef TCP_CALCULATE_EFF_SEND_MSS
-#define TCP_CALCULATE_EFF_SEND_MSS 1
-#endif
-
-
-/**
- * TCP_SND_BUF: TCP sender buffer space (bytes).
- */
-#ifndef TCP_SND_BUF
-#define TCP_SND_BUF 256
-#endif
-
-/**
- * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least
- * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work.
- */
-#ifndef TCP_SND_QUEUELEN
-#define TCP_SND_QUEUELEN (4 * (TCP_SND_BUF/TCP_MSS))
-#endif
-
-/**
- * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than or equal
- * to TCP_SND_BUF. It is the amount of space which must be available in the
- * TCP snd_buf for select to return writable.
- */
-#ifndef TCP_SNDLOWAT
-#define TCP_SNDLOWAT (TCP_SND_BUF/2)
-#endif
-
-/**
- * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb.
- */
-#ifndef TCP_LISTEN_BACKLOG
-#define TCP_LISTEN_BACKLOG 0
-#endif
-
-/**
- * The maximum allowed backlog for TCP listen netconns.
- * This backlog is used unless another is explicitly specified.
- * 0xff is the maximum (u8_t).
- */
-#ifndef TCP_DEFAULT_LISTEN_BACKLOG
-#define TCP_DEFAULT_LISTEN_BACKLOG 0xff
-#endif
-
-/**
- * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1.
- * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all
- * events (accept, sent, etc) that happen in the system.
- * LWIP_CALLBACK_API==1: The PCB callback function is called directly
- * for the event.
- */
-#ifndef LWIP_EVENT_API
-#define LWIP_EVENT_API 0
-#define LWIP_CALLBACK_API 1
-#else
-#define LWIP_EVENT_API 1
-#define LWIP_CALLBACK_API 0
-#endif
-
-
-/*
- ----------------------------------
- ---------- Pbuf options ----------
- ----------------------------------
-*/
-/**
- * PBUF_LINK_HLEN: the number of bytes that should be allocated for a
- * link level header. The default is 14, the standard value for
- * Ethernet.
- */
-#ifndef PBUF_LINK_HLEN
-#define PBUF_LINK_HLEN 14
-#endif
-
-/**
- * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is
- * designed to accomodate single full size TCP frame in one pbuf, including
- * TCP_MSS, IP header, and link header.
- */
-#ifndef PBUF_POOL_BUFSIZE
-#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN)
-#endif
-
-/*
- ------------------------------------------------
- ---------- Network Interfaces options ----------
- ------------------------------------------------
-*/
-/**
- * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname
- * field.
- */
-#ifndef LWIP_NETIF_HOSTNAME
-#define LWIP_NETIF_HOSTNAME 0
-#endif
-
-/**
- * LWIP_NETIF_API==1: Support netif api (in netifapi.c)
- */
-#ifndef LWIP_NETIF_API
-#define LWIP_NETIF_API 0
-#endif
-
-/**
- * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface
- * changes its up/down status (i.e., due to DHCP IP acquistion)
- */
-#ifndef LWIP_NETIF_STATUS_CALLBACK
-#define LWIP_NETIF_STATUS_CALLBACK 0
-#endif
-
-/**
- * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface
- * whenever the link changes (i.e., link down)
- */
-#ifndef LWIP_NETIF_LINK_CALLBACK
-#define LWIP_NETIF_LINK_CALLBACK 0
-#endif
-
-/**
- * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table
- * indices) in struct netif. TCP and UDP can make use of this to prevent
- * scanning the ARP table for every sent packet. While this is faster for big
- * ARP tables or many concurrent connections, it might be counterproductive
- * if you have a tiny ARP table or if there never are concurrent connections.
- */
-#ifndef LWIP_NETIF_HWADDRHINT
-#define LWIP_NETIF_HWADDRHINT 0
-#endif
-
-/*
- ------------------------------------
- ---------- LOOPIF options ----------
- ------------------------------------
-*/
-/**
- * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c
- */
-#ifndef LWIP_HAVE_LOOPIF
-#define LWIP_HAVE_LOOPIF 0
-#endif
-
-/**
- * LWIP_LOOPIF_MULTITHREADING: Indicates whether threading is enabled in
- * the system, as LOOPIF must change how it behaves depending on this setting.
- * Setting this is needed to avoid reentering non-reentrant functions like
- * tcp_input().
- * LWIP_LOOPIF_MULTITHREADING==1: Indicates that the user is using a
- * multithreaded environment like tcpip.c. In this case, netif->input()
- * is called directly.
- * LWIP_LOOPIF_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup.
- * The packets are put on a list and loopif_poll() must be called in
- * the main application loop.
- */
-#ifndef LWIP_LOOPIF_MULTITHREADING
-#define LWIP_LOOPIF_MULTITHREADING 1
-#endif
-
-/*
- ------------------------------------
- ---------- Thread options ----------
- ------------------------------------
-*/
-/**
- * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread.
- */
-#ifndef TCPIP_THREAD_NAME
-#define TCPIP_THREAD_NAME "tcpip_thread"
-#endif
-
-/**
- * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread.
- * The stack size value itself is platform-dependent, but is passed to
- * sys_thread_new() when the thread is created.
- */
-#ifndef TCPIP_THREAD_STACKSIZE
-#define TCPIP_THREAD_STACKSIZE 0
-#endif
-
-/**
- * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread.
- * The priority value itself is platform-dependent, but is passed to
- * sys_thread_new() when the thread is created.
- */
-#ifndef TCPIP_THREAD_PRIO
-#define TCPIP_THREAD_PRIO 1
-#endif
-
-/**
- * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages
- * The queue size value itself is platform-dependent, but is passed to
- * sys_mbox_new() when tcpip_init is called.
- */
-#ifndef TCPIP_MBOX_SIZE
-#define TCPIP_MBOX_SIZE 0
-#endif
-
-/**
- * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread.
- */
-#ifndef SLIPIF_THREAD_NAME
-#define SLIPIF_THREAD_NAME "slipif_loop"
-#endif
-
-/**
- * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread.
- * The stack size value itself is platform-dependent, but is passed to
- * sys_thread_new() when the thread is created.
- */
-#ifndef SLIPIF_THREAD_STACKSIZE
-#define SLIPIF_THREAD_STACKSIZE 0
-#endif
-
-/**
- * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread.
- * The priority value itself is platform-dependent, but is passed to
- * sys_thread_new() when the thread is created.
- */
-#ifndef SLIPIF_THREAD_PRIO
-#define SLIPIF_THREAD_PRIO 1
-#endif
-
-/**
- * PPP_THREAD_NAME: The name assigned to the pppMain thread.
- */
-#ifndef PPP_THREAD_NAME
-#define PPP_THREAD_NAME "pppMain"
-#endif
-
-/**
- * PPP_THREAD_STACKSIZE: The stack size used by the pppMain thread.
- * The stack size value itself is platform-dependent, but is passed to
- * sys_thread_new() when the thread is created.
- */
-#ifndef PPP_THREAD_STACKSIZE
-#define PPP_THREAD_STACKSIZE 0
-#endif
-
-/**
- * PPP_THREAD_PRIO: The priority assigned to the pppMain thread.
- * The priority value itself is platform-dependent, but is passed to
- * sys_thread_new() when the thread is created.
- */
-#ifndef PPP_THREAD_PRIO
-#define PPP_THREAD_PRIO 1
-#endif
-
-/**
- * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread.
- */
-#ifndef DEFAULT_THREAD_NAME
-#define DEFAULT_THREAD_NAME "lwIP"
-#endif
-
-/**
- * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread.
- * The stack size value itself is platform-dependent, but is passed to
- * sys_thread_new() when the thread is created.
- */
-#ifndef DEFAULT_THREAD_STACKSIZE
-#define DEFAULT_THREAD_STACKSIZE 0
-#endif
-
-/**
- * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread.
- * The priority value itself is platform-dependent, but is passed to
- * sys_thread_new() when the thread is created.
- */
-#ifndef DEFAULT_THREAD_PRIO
-#define DEFAULT_THREAD_PRIO 1
-#endif
-
-/**
- * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a
- * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed
- * to sys_mbox_new() when the recvmbox is created.
- */
-#ifndef DEFAULT_RAW_RECVMBOX_SIZE
-#define DEFAULT_RAW_RECVMBOX_SIZE 0
-#endif
-
-/**
- * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a
- * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed
- * to sys_mbox_new() when the recvmbox is created.
- */
-#ifndef DEFAULT_UDP_RECVMBOX_SIZE
-#define DEFAULT_UDP_RECVMBOX_SIZE 0
-#endif
-
-/**
- * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a
- * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed
- * to sys_mbox_new() when the recvmbox is created.
- */
-#ifndef DEFAULT_TCP_RECVMBOX_SIZE
-#define DEFAULT_TCP_RECVMBOX_SIZE 0
-#endif
-
-/**
- * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections.
- * The queue size value itself is platform-dependent, but is passed to
- * sys_mbox_new() when the acceptmbox is created.
- */
-#ifndef DEFAULT_ACCEPTMBOX_SIZE
-#define DEFAULT_ACCEPTMBOX_SIZE 0
-#endif
-
-/*
- ----------------------------------------------
- ---------- Sequential layer options ----------
- ----------------------------------------------
-*/
-/**
- * LWIP_TCPIP_CORE_LOCKING: (EXPERIMENTAL!)
- * Don't use it if you're not an active lwIP project member
- */
-#ifndef LWIP_TCPIP_CORE_LOCKING
-#define LWIP_TCPIP_CORE_LOCKING 0
-#endif
-
-/**
- * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
- */
-#ifndef LWIP_NETCONN
-#define LWIP_NETCONN 1
-#endif
-
-/*
- ------------------------------------
- ---------- Socket options ----------
- ------------------------------------
-*/
-/**
- * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
- */
-#ifndef LWIP_SOCKET
-#define LWIP_SOCKET 1
-#endif
-
-/**
- * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names.
- * (only used if you use sockets.c)
- */
-#ifndef LWIP_COMPAT_SOCKETS
-#define LWIP_COMPAT_SOCKETS 1
-#endif
-
-/**
- * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names.
- * Disable this option if you use a POSIX operating system that uses the same
- * names (read, write & close). (only used if you use sockets.c)
- */
-#ifndef LWIP_POSIX_SOCKETS_IO_NAMES
-#define LWIP_POSIX_SOCKETS_IO_NAMES 1
-#endif
-
-/**
- * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT
- * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set
- * in seconds. (does not require sockets.c, and will affect tcp.c)
- */
-#ifndef LWIP_TCP_KEEPALIVE
-#define LWIP_TCP_KEEPALIVE 0
-#endif
-
-/**
- * LWIP_SO_RCVTIMEO==1: Enable SO_RCVTIMEO processing.
- */
-#ifndef LWIP_SO_RCVTIMEO
-#define LWIP_SO_RCVTIMEO 0
-#endif
-
-/**
- * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing.
- */
-#ifndef LWIP_SO_RCVBUF
-#define LWIP_SO_RCVBUF 0
-#endif
-
-/**
- * SO_REUSE==1: Enable SO_REUSEADDR and SO_REUSEPORT options. DO NOT USE!
- */
-#ifndef SO_REUSE
-#define SO_REUSE 0
-#endif
-
-/*
- ----------------------------------------
- ---------- Statistics options ----------
- ----------------------------------------
-*/
-/**
- * LWIP_STATS==1: Enable statistics collection in lwip_stats.
- */
-#ifndef LWIP_STATS
-#define LWIP_STATS 1
-#endif
-
-#if LWIP_STATS
-
-/**
- * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions.
- */
-#ifndef LWIP_STATS_DISPLAY
-#define LWIP_STATS_DISPLAY 0
-#endif
-
-/**
- * LINK_STATS==1: Enable link stats.
- */
-#ifndef LINK_STATS
-#define LINK_STATS 1
-#endif
-
-/**
- * ETHARP_STATS==1: Enable etharp stats.
- */
-#ifndef ETHARP_STATS
-#define ETHARP_STATS (LWIP_ARP)
-#endif
-
-/**
- * IP_STATS==1: Enable IP stats.
- */
-#ifndef IP_STATS
-#define IP_STATS 1
-#endif
-
-/**
- * IPFRAG_STATS==1: Enable IP fragmentation stats. Default is
- * on if using either frag or reass.
- */
-#ifndef IPFRAG_STATS
-#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG)
-#endif
-
-/**
- * ICMP_STATS==1: Enable ICMP stats.
- */
-#ifndef ICMP_STATS
-#define ICMP_STATS 1
-#endif
-
-/**
- * IGMP_STATS==1: Enable IGMP stats.
- */
-#ifndef IGMP_STATS
-#define IGMP_STATS (LWIP_IGMP)
-#endif
-
-/**
- * UDP_STATS==1: Enable UDP stats. Default is on if
- * UDP enabled, otherwise off.
- */
-#ifndef UDP_STATS
-#define UDP_STATS (LWIP_UDP)
-#endif
-
-/**
- * TCP_STATS==1: Enable TCP stats. Default is on if TCP
- * enabled, otherwise off.
- */
-#ifndef TCP_STATS
-#define TCP_STATS (LWIP_TCP)
-#endif
-
-/**
- * MEM_STATS==1: Enable mem.c stats.
- */
-#ifndef MEM_STATS
-#define MEM_STATS 1
-#endif
-
-/**
- * MEMP_STATS==1: Enable memp.c pool stats.
- */
-#ifndef MEMP_STATS
-#define MEMP_STATS 1
-#endif
-
-/**
- * SYS_STATS==1: Enable system stats (sem and mbox counts, etc).
- */
-#ifndef SYS_STATS
-#define SYS_STATS 1
-#endif
-
-#else
-
-#define LINK_STATS 0
-#define IP_STATS 0
-#define IPFRAG_STATS 0
-#define ICMP_STATS 0
-#define IGMP_STATS 0
-#define UDP_STATS 0
-#define TCP_STATS 0
-#define MEM_STATS 0
-#define MEMP_STATS 0
-#define SYS_STATS 0
-#define LWIP_STATS_DISPLAY 0
-
-#endif /* LWIP_STATS */
-
-/*
- ---------------------------------
- ---------- PPP options ----------
- ---------------------------------
-*/
-/**
- * PPP_SUPPORT==1: Enable PPP.
- */
-#ifndef PPP_SUPPORT
-#define PPP_SUPPORT 0
-#endif
-
-/**
- * PPPOE_SUPPORT==1: Enable PPP Over Ethernet
- */
-#ifndef PPPOE_SUPPORT
-#define PPPOE_SUPPORT 0
-#endif
-
-/**
- * PPPOS_SUPPORT==1: Enable PPP Over Serial
- */
-#ifndef PPPOS_SUPPORT
-#define PPPOS_SUPPORT PPP_SUPPORT
-#endif
-
-#if PPP_SUPPORT
-
-/**
- * NUM_PPP: Max PPP sessions.
- */
-#ifndef NUM_PPP
-#define NUM_PPP 1
-#endif
-
-/**
- * PAP_SUPPORT==1: Support PAP.
- */
-#ifndef PAP_SUPPORT
-#define PAP_SUPPORT 0
-#endif
-
-/**
- * CHAP_SUPPORT==1: Support CHAP.
- */
-#ifndef CHAP_SUPPORT
-#define CHAP_SUPPORT 0
-#endif
-
-/**
- * MSCHAP_SUPPORT==1: Support MSCHAP. CURRENTLY NOT SUPPORTED! DO NOT SET!
- */
-#ifndef MSCHAP_SUPPORT
-#define MSCHAP_SUPPORT 0
-#endif
-
-/**
- * CBCP_SUPPORT==1: Support CBCP. CURRENTLY NOT SUPPORTED! DO NOT SET!
- */
-#ifndef CBCP_SUPPORT
-#define CBCP_SUPPORT 0
-#endif
-
-/**
- * CCP_SUPPORT==1: Support CCP. CURRENTLY NOT SUPPORTED! DO NOT SET!
- */
-#ifndef CCP_SUPPORT
-#define CCP_SUPPORT 0
-#endif
-
-/**
- * VJ_SUPPORT==1: Support VJ header compression.
- */
-#ifndef VJ_SUPPORT
-#define VJ_SUPPORT 0
-#endif
-
-/**
- * MD5_SUPPORT==1: Support MD5 (see also CHAP).
- */
-#ifndef MD5_SUPPORT
-#define MD5_SUPPORT 0
-#endif
-
-/*
- * Timeouts
- */
-#ifndef FSM_DEFTIMEOUT
-#define FSM_DEFTIMEOUT 6 /* Timeout time in seconds */
-#endif
-
-#ifndef FSM_DEFMAXTERMREQS
-#define FSM_DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */
-#endif
-
-#ifndef FSM_DEFMAXCONFREQS
-#define FSM_DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */
-#endif
-
-#ifndef FSM_DEFMAXNAKLOOPS
-#define FSM_DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */
-#endif
-
-#ifndef UPAP_DEFTIMEOUT
-#define UPAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */
-#endif
-
-#ifndef UPAP_DEFREQTIME
-#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */
-#endif
-
-#ifndef CHAP_DEFTIMEOUT
-#define CHAP_DEFTIMEOUT 6 /* Timeout time in seconds */
-#endif
-
-#ifndef CHAP_DEFTRANSMITS
-#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */
-#endif
-
-/* Interval in seconds between keepalive echo requests, 0 to disable. */
-#ifndef LCP_ECHOINTERVAL
-#define LCP_ECHOINTERVAL 0
-#endif
-
-/* Number of unanswered echo requests before failure. */
-#ifndef LCP_MAXECHOFAILS
-#define LCP_MAXECHOFAILS 3
-#endif
-
-/* Max Xmit idle time (in jiffies) before resend flag char. */
-#ifndef PPP_MAXIDLEFLAG
-#define PPP_MAXIDLEFLAG 100
-#endif
-
-/*
- * Packet sizes
- *
- * Note - lcp shouldn't be allowed to negotiate stuff outside these
- * limits. See lcp.h in the pppd directory.
- * (XXX - these constants should simply be shared by lcp.c instead
- * of living in lcp.h)
- */
-#define PPP_MTU 1500 /* Default MTU (size of Info field) */
-#ifndef PPP_MAXMTU
-/* #define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) */
-#define PPP_MAXMTU 1500 /* Largest MTU we allow */
-#endif
-#define PPP_MINMTU 64
-#define PPP_MRU 1500 /* default MRU = max length of info field */
-#define PPP_MAXMRU 1500 /* Largest MRU we allow */
-#ifndef PPP_DEFMRU
-#define PPP_DEFMRU 296 /* Try for this */
-#endif
-#define PPP_MINMRU 128 /* No MRUs below this */
-
-
-#define MAXNAMELEN 256 /* max length of hostname or name for auth */
-#define MAXSECRETLEN 256 /* max length of password or secret */
-
-#endif /* PPP_SUPPORT */
-
-/*
- --------------------------------------
- ---------- Checksum options ----------
- --------------------------------------
-*/
-/**
- * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.
- */
-#ifndef CHECKSUM_GEN_IP
-#define CHECKSUM_GEN_IP 1
-#endif
-
-/**
- * CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.
- */
-#ifndef CHECKSUM_GEN_UDP
-#define CHECKSUM_GEN_UDP 1
-#endif
-
-/**
- * CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.
- */
-#ifndef CHECKSUM_GEN_TCP
-#define CHECKSUM_GEN_TCP 1
-#endif
-
-/**
- * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.
- */
-#ifndef CHECKSUM_CHECK_IP
-#define CHECKSUM_CHECK_IP 1
-#endif
-
-/**
- * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.
- */
-#ifndef CHECKSUM_CHECK_UDP
-#define CHECKSUM_CHECK_UDP 1
-#endif
-
-/**
- * CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.
- */
-#ifndef CHECKSUM_CHECK_TCP
-#define CHECKSUM_CHECK_TCP 1
-#endif
-
-/*
- ---------------------------------------
- ---------- Debugging options ----------
- ---------------------------------------
-*/
-/**
- * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is
- * compared against this value. If it is smaller, then debugging
- * messages are written.
- */
-#ifndef LWIP_DBG_MIN_LEVEL
-#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_OFF
-#endif
-
-/**
- * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable
- * debug messages of certain types.
- */
-#ifndef LWIP_DBG_TYPES_ON
-#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
-#endif
-
-/**
- * ETHARP_DEBUG: Enable debugging in etharp.c.
- */
-#ifndef ETHARP_DEBUG
-#define ETHARP_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * NETIF_DEBUG: Enable debugging in netif.c.
- */
-#ifndef NETIF_DEBUG
-#define NETIF_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * PBUF_DEBUG: Enable debugging in pbuf.c.
- */
-#ifndef PBUF_DEBUG
-#define PBUF_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * API_LIB_DEBUG: Enable debugging in api_lib.c.
- */
-#ifndef API_LIB_DEBUG
-#define API_LIB_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * API_MSG_DEBUG: Enable debugging in api_msg.c.
- */
-#ifndef API_MSG_DEBUG
-#define API_MSG_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * SOCKETS_DEBUG: Enable debugging in sockets.c.
- */
-#ifndef SOCKETS_DEBUG
-#define SOCKETS_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * ICMP_DEBUG: Enable debugging in icmp.c.
- */
-#ifndef ICMP_DEBUG
-#define ICMP_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * IGMP_DEBUG: Enable debugging in igmp.c.
- */
-#ifndef IGMP_DEBUG
-#define IGMP_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * INET_DEBUG: Enable debugging in inet.c.
- */
-#ifndef INET_DEBUG
-#define INET_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * IP_DEBUG: Enable debugging for IP.
- */
-#ifndef IP_DEBUG
-#define IP_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass.
- */
-#ifndef IP_REASS_DEBUG
-#define IP_REASS_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * RAW_DEBUG: Enable debugging in raw.c.
- */
-#ifndef RAW_DEBUG
-#define RAW_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * MEM_DEBUG: Enable debugging in mem.c.
- */
-#ifndef MEM_DEBUG
-#define MEM_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * MEMP_DEBUG: Enable debugging in memp.c.
- */
-#ifndef MEMP_DEBUG
-#define MEMP_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * SYS_DEBUG: Enable debugging in sys.c.
- */
-#ifndef SYS_DEBUG
-#define SYS_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * TCP_DEBUG: Enable debugging for TCP.
- */
-#ifndef TCP_DEBUG
-#define TCP_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug.
- */
-#ifndef TCP_INPUT_DEBUG
-#define TCP_INPUT_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit.
- */
-#ifndef TCP_FR_DEBUG
-#define TCP_FR_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit
- * timeout.
- */
-#ifndef TCP_RTO_DEBUG
-#define TCP_RTO_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * TCP_CWND_DEBUG: Enable debugging for TCP congestion window.
- */
-#ifndef TCP_CWND_DEBUG
-#define TCP_CWND_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating.
- */
-#ifndef TCP_WND_DEBUG
-#define TCP_WND_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions.
- */
-#ifndef TCP_OUTPUT_DEBUG
-#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * TCP_RST_DEBUG: Enable debugging for TCP with the RST message.
- */
-#ifndef TCP_RST_DEBUG
-#define TCP_RST_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths.
- */
-#ifndef TCP_QLEN_DEBUG
-#define TCP_QLEN_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * UDP_DEBUG: Enable debugging in UDP.
- */
-#ifndef UDP_DEBUG
-#define UDP_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * TCPIP_DEBUG: Enable debugging in tcpip.c.
- */
-#ifndef TCPIP_DEBUG
-#define TCPIP_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * PPP_DEBUG: Enable debugging for PPP.
- */
-#ifndef PPP_DEBUG
-#define PPP_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * SLIP_DEBUG: Enable debugging in slipif.c.
- */
-#ifndef SLIP_DEBUG
-#define SLIP_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * DHCP_DEBUG: Enable debugging in dhcp.c.
- */
-#ifndef DHCP_DEBUG
-#define DHCP_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * AUTOIP_DEBUG: Enable debugging in autoip.c.
- */
-#ifndef AUTOIP_DEBUG
-#define AUTOIP_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * SNMP_MSG_DEBUG: Enable debugging for SNMP messages.
- */
-#ifndef SNMP_MSG_DEBUG
-#define SNMP_MSG_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs.
- */
-#ifndef SNMP_MIB_DEBUG
-#define SNMP_MIB_DEBUG LWIP_DBG_OFF
-#endif
-
-/**
- * DNS_DEBUG: Enable debugging for DNS.
- */
-#ifndef DNS_DEBUG
-#define DNS_DEBUG LWIP_DBG_OFF
-#endif
-
-#endif /* __LWIP_OPT_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-#ifndef __LWIP_PBUF_H__
-#define __LWIP_PBUF_H__
-
-#include "lwip/opt.h"
-#include "lwip/err.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define PBUF_TRANSPORT_HLEN 20
-#define PBUF_IP_HLEN 20
-
-typedef enum {
- PBUF_TRANSPORT,
- PBUF_IP,
- PBUF_LINK,
- PBUF_RAW
-} pbuf_layer;
-
-typedef enum {
- PBUF_RAM, /* pbuf data is stored in RAM */
- PBUF_ROM, /* pbuf data is stored in ROM */
- PBUF_REF, /* pbuf comes from the pbuf pool */
- PBUF_POOL /* pbuf payload refers to RAM */
-} pbuf_type;
-
-
-/** indicates this packet's data should be immediately passed to the application */
-#define PBUF_FLAG_PUSH 0x01U
-
-struct pbuf {
- /** next pbuf in singly linked pbuf chain */
- struct pbuf *next;
-
- /** pointer to the actual data in the buffer */
- void *payload;
-
- /**
- * total length of this buffer and all next buffers in chain
- * belonging to the same packet.
- *
- * For non-queue packet chains this is the invariant:
- * p->tot_len == p->len + (p->next? p->next->tot_len: 0)
- */
- u16_t tot_len;
-
- /** length of this buffer */
- u16_t len;
-
- /** pbuf_type as u8_t instead of enum to save space */
- u8_t /*pbuf_type*/ type;
-
- /** misc flags */
- u8_t flags;
-
- /**
- * the reference count always equals the number of pointers
- * that refer to this pbuf. This can be pointers from an application,
- * the stack itself, or pbuf->next pointers from a chain.
- */
- u16_t ref;
-
-};
-
-/* Initializes the pbuf module. This call is empty for now, but may not be in future. */
-#define pbuf_init()
-
-struct pbuf *pbuf_alloc(pbuf_layer l, u16_t size, pbuf_type type);
-void pbuf_realloc(struct pbuf *p, u16_t size);
-u8_t pbuf_header(struct pbuf *p, s16_t header_size);
-void pbuf_ref(struct pbuf *p);
-void pbuf_ref_chain(struct pbuf *p);
-u8_t pbuf_free(struct pbuf *p);
-u8_t pbuf_clen(struct pbuf *p);
-void pbuf_cat(struct pbuf *head, struct pbuf *tail);
-void pbuf_chain(struct pbuf *head, struct pbuf *tail);
-struct pbuf *pbuf_dechain(struct pbuf *p);
-err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from);
-u16_t pbuf_copy_partial(struct pbuf *p, void *dataptr, u16_t len, u16_t offset);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_PBUF_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_RAW_H__
-#define __LWIP_RAW_H__
-
-#include "lwip/opt.h"
-
-#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/pbuf.h"
-#include "lwip/inet.h"
-#include "lwip/ip.h"
-#include "lwip/ip_addr.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct raw_pcb {
-/* Common members of all PCB types */
- IP_PCB;
-
- struct raw_pcb *next;
-
- u8_t protocol;
-
- /* receive callback function
- * @param arg user supplied argument (raw_pcb.recv_arg)
- * @param pcb the raw_pcb which received data
- * @param p the packet buffer that was received
- * @param addr the remote IP address from which the packet was received
- * @return 1 if the packet was 'eaten' (aka. deleted),
- * 0 if the packet lives on
- * If returning 1, the callback is responsible for freeing the pbuf
- * if it's not used any more.
- */
- u8_t (* recv)(void *arg, struct raw_pcb *pcb, struct pbuf *p,
- struct ip_addr *addr);
- /* user-supplied argument for the recv callback */
- void *recv_arg;
-};
-
-/* The following functions is the application layer interface to the
- RAW code. */
-struct raw_pcb * raw_new (u8_t proto);
-void raw_remove (struct raw_pcb *pcb);
-err_t raw_bind (struct raw_pcb *pcb, struct ip_addr *ipaddr);
-err_t raw_connect (struct raw_pcb *pcb, struct ip_addr *ipaddr);
-
-void raw_recv (struct raw_pcb *pcb,
- u8_t (* recv)(void *arg, struct raw_pcb *pcb,
- struct pbuf *p,
- struct ip_addr *addr),
- void *recv_arg);
-err_t raw_sendto (struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr);
-err_t raw_send (struct raw_pcb *pcb, struct pbuf *p);
-
-/* The following functions are the lower layer interface to RAW. */
-u8_t raw_input (struct pbuf *p, struct netif *inp);
-#define raw_init() /* Compatibility define, not init needed. */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_RAW */
-
-#endif /* __LWIP_RAW_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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 the interface to the platform specific serial IO module
- * It needs to be implemented by those platforms which need SLIP or PPP
- */
-
-#include "lwip/arch.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __sio_fd_t_defined
-typedef void * sio_fd_t;
-#endif
-
-#ifndef sio_open
-sio_fd_t sio_open(u8_t);
-#endif
-
-#ifndef sio_send
-void sio_send(u8_t, sio_fd_t);
-#endif
-
-#ifndef sio_recv
-u8_t sio_recv(sio_fd_t);
-#endif
-
-#ifndef sio_read
-u32_t sio_read(sio_fd_t, u8_t *, u32_t);
-#endif
-
-#ifndef sio_write
-u32_t sio_write(sio_fd_t, u8_t *, u32_t);
-#endif
-
-#ifndef sio_read_abort
-void sio_read_abort(sio_fd_t);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2001, 2002 Leon Woestenberg <leon.woestenberg@axon.tv>
- * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Leon Woestenberg <leon.woestenberg@axon.tv>
- *
- */
-#ifndef __LWIP_SNMP_H__
-#define __LWIP_SNMP_H__
-
-#include "lwip/opt.h"
-#include "lwip/netif.h"
-#include "lwip/udp.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @see RFC1213, "MIB-II, 6. Definitions"
- */
-enum snmp_ifType {
- snmp_ifType_other=1, /* none of the following */
- snmp_ifType_regular1822,
- snmp_ifType_hdh1822,
- snmp_ifType_ddn_x25,
- snmp_ifType_rfc877_x25,
- snmp_ifType_ethernet_csmacd,
- snmp_ifType_iso88023_csmacd,
- snmp_ifType_iso88024_tokenBus,
- snmp_ifType_iso88025_tokenRing,
- snmp_ifType_iso88026_man,
- snmp_ifType_starLan,
- snmp_ifType_proteon_10Mbit,
- snmp_ifType_proteon_80Mbit,
- snmp_ifType_hyperchannel,
- snmp_ifType_fddi,
- snmp_ifType_lapb,
- snmp_ifType_sdlc,
- snmp_ifType_ds1, /* T-1 */
- snmp_ifType_e1, /* european equiv. of T-1 */
- snmp_ifType_basicISDN,
- snmp_ifType_primaryISDN, /* proprietary serial */
- snmp_ifType_propPointToPointSerial,
- snmp_ifType_ppp,
- snmp_ifType_softwareLoopback,
- snmp_ifType_eon, /* CLNP over IP [11] */
- snmp_ifType_ethernet_3Mbit,
- snmp_ifType_nsip, /* XNS over IP */
- snmp_ifType_slip, /* generic SLIP */
- snmp_ifType_ultra, /* ULTRA technologies */
- snmp_ifType_ds3, /* T-3 */
- snmp_ifType_sip, /* SMDS */
- snmp_ifType_frame_relay
-};
-
-#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
-
-/** SNMP "sysuptime" Interval */
-#define SNMP_SYSUPTIME_INTERVAL 10
-
-/** fixed maximum length for object identifier type */
-#define LWIP_SNMP_OBJ_ID_LEN 32
-
-/** internal object identifier representation */
-struct snmp_obj_id
-{
- u8_t len;
- s32_t id[LWIP_SNMP_OBJ_ID_LEN];
-};
-
-/* system */
-void snmp_set_sysdesr(u8_t* str, u8_t* len);
-void snmp_set_sysobjid(struct snmp_obj_id *oid);
-void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid);
-void snmp_inc_sysuptime(void);
-void snmp_add_sysuptime(u32_t value);
-void snmp_get_sysuptime(u32_t *value);
-void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen);
-void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen);
-void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen);
-
-/* network interface */
-void snmp_add_ifinoctets(struct netif *ni, u32_t value);
-void snmp_inc_ifinucastpkts(struct netif *ni);
-void snmp_inc_ifinnucastpkts(struct netif *ni);
-void snmp_inc_ifindiscards(struct netif *ni);
-void snmp_add_ifoutoctets(struct netif *ni, u32_t value);
-void snmp_inc_ifoutucastpkts(struct netif *ni);
-void snmp_inc_ifoutnucastpkts(struct netif *ni);
-void snmp_inc_ifoutdiscards(struct netif *ni);
-void snmp_inc_iflist(void);
-void snmp_dec_iflist(void);
-
-/* ARP (for atTable and ipNetToMediaTable) */
-void snmp_insert_arpidx_tree(struct netif *ni, struct ip_addr *ip);
-void snmp_delete_arpidx_tree(struct netif *ni, struct ip_addr *ip);
-
-/* IP */
-void snmp_inc_ipinreceives(void);
-void snmp_inc_ipinhdrerrors(void);
-void snmp_inc_ipinaddrerrors(void);
-void snmp_inc_ipforwdatagrams(void);
-void snmp_inc_ipinunknownprotos(void);
-void snmp_inc_ipindiscards(void);
-void snmp_inc_ipindelivers(void);
-void snmp_inc_ipoutrequests(void);
-void snmp_inc_ipoutdiscards(void);
-void snmp_inc_ipoutnoroutes(void);
-void snmp_inc_ipreasmreqds(void);
-void snmp_inc_ipreasmoks(void);
-void snmp_inc_ipreasmfails(void);
-void snmp_inc_ipfragoks(void);
-void snmp_inc_ipfragfails(void);
-void snmp_inc_ipfragcreates(void);
-void snmp_inc_iproutingdiscards(void);
-void snmp_insert_ipaddridx_tree(struct netif *ni);
-void snmp_delete_ipaddridx_tree(struct netif *ni);
-void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni);
-void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni);
-
-/* ICMP */
-void snmp_inc_icmpinmsgs(void);
-void snmp_inc_icmpinerrors(void);
-void snmp_inc_icmpindestunreachs(void);
-void snmp_inc_icmpintimeexcds(void);
-void snmp_inc_icmpinparmprobs(void);
-void snmp_inc_icmpinsrcquenchs(void);
-void snmp_inc_icmpinredirects(void);
-void snmp_inc_icmpinechos(void);
-void snmp_inc_icmpinechoreps(void);
-void snmp_inc_icmpintimestamps(void);
-void snmp_inc_icmpintimestampreps(void);
-void snmp_inc_icmpinaddrmasks(void);
-void snmp_inc_icmpinaddrmaskreps(void);
-void snmp_inc_icmpoutmsgs(void);
-void snmp_inc_icmpouterrors(void);
-void snmp_inc_icmpoutdestunreachs(void);
-void snmp_inc_icmpouttimeexcds(void);
-void snmp_inc_icmpoutparmprobs(void);
-void snmp_inc_icmpoutsrcquenchs(void);
-void snmp_inc_icmpoutredirects(void);
-void snmp_inc_icmpoutechos(void);
-void snmp_inc_icmpoutechoreps(void);
-void snmp_inc_icmpouttimestamps(void);
-void snmp_inc_icmpouttimestampreps(void);
-void snmp_inc_icmpoutaddrmasks(void);
-void snmp_inc_icmpoutaddrmaskreps(void);
-
-/* TCP */
-void snmp_inc_tcpactiveopens(void);
-void snmp_inc_tcppassiveopens(void);
-void snmp_inc_tcpattemptfails(void);
-void snmp_inc_tcpestabresets(void);
-void snmp_inc_tcpinsegs(void);
-void snmp_inc_tcpoutsegs(void);
-void snmp_inc_tcpretranssegs(void);
-void snmp_inc_tcpinerrs(void);
-void snmp_inc_tcpoutrsts(void);
-
-/* UDP */
-void snmp_inc_udpindatagrams(void);
-void snmp_inc_udpnoports(void);
-void snmp_inc_udpinerrors(void);
-void snmp_inc_udpoutdatagrams(void);
-void snmp_insert_udpidx_tree(struct udp_pcb *pcb);
-void snmp_delete_udpidx_tree(struct udp_pcb *pcb);
-
-/* SNMP */
-void snmp_inc_snmpinpkts(void);
-void snmp_inc_snmpoutpkts(void);
-void snmp_inc_snmpinbadversions(void);
-void snmp_inc_snmpinbadcommunitynames(void);
-void snmp_inc_snmpinbadcommunityuses(void);
-void snmp_inc_snmpinasnparseerrs(void);
-void snmp_inc_snmpintoobigs(void);
-void snmp_inc_snmpinnosuchnames(void);
-void snmp_inc_snmpinbadvalues(void);
-void snmp_inc_snmpinreadonlys(void);
-void snmp_inc_snmpingenerrs(void);
-void snmp_add_snmpintotalreqvars(u8_t value);
-void snmp_add_snmpintotalsetvars(u8_t value);
-void snmp_inc_snmpingetrequests(void);
-void snmp_inc_snmpingetnexts(void);
-void snmp_inc_snmpinsetrequests(void);
-void snmp_inc_snmpingetresponses(void);
-void snmp_inc_snmpintraps(void);
-void snmp_inc_snmpouttoobigs(void);
-void snmp_inc_snmpoutnosuchnames(void);
-void snmp_inc_snmpoutbadvalues(void);
-void snmp_inc_snmpoutgenerrs(void);
-void snmp_inc_snmpoutgetrequests(void);
-void snmp_inc_snmpoutgetnexts(void);
-void snmp_inc_snmpoutsetrequests(void);
-void snmp_inc_snmpoutgetresponses(void);
-void snmp_inc_snmpouttraps(void);
-void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid);
-void snmp_set_snmpenableauthentraps(u8_t *value);
-void snmp_get_snmpenableauthentraps(u8_t *value);
-
-/* LWIP_SNMP support not available */
-/* define everything to be empty */
-#else
-
-/* system */
-#define snmp_set_sysdesr(str, len)
-#define snmp_set_sysobjid(oid);
-#define snmp_get_sysobjid_ptr(oid)
-#define snmp_inc_sysuptime()
-#define snmp_add_sysuptime(value)
-#define snmp_get_sysuptime(value)
-#define snmp_set_syscontact(ocstr, ocstrlen);
-#define snmp_set_sysname(ocstr, ocstrlen);
-#define snmp_set_syslocation(ocstr, ocstrlen);
-
-/* network interface */
-#define snmp_add_ifinoctets(ni,value)
-#define snmp_inc_ifinucastpkts(ni)
-#define snmp_inc_ifinnucastpkts(ni)
-#define snmp_inc_ifindiscards(ni)
-#define snmp_add_ifoutoctets(ni,value)
-#define snmp_inc_ifoutucastpkts(ni)
-#define snmp_inc_ifoutnucastpkts(ni)
-#define snmp_inc_ifoutdiscards(ni)
-#define snmp_inc_iflist()
-#define snmp_dec_iflist()
-
-/* ARP */
-#define snmp_insert_arpidx_tree(ni,ip)
-#define snmp_delete_arpidx_tree(ni,ip)
-
-/* IP */
-#define snmp_inc_ipinreceives()
-#define snmp_inc_ipinhdrerrors()
-#define snmp_inc_ipinaddrerrors()
-#define snmp_inc_ipforwdatagrams()
-#define snmp_inc_ipinunknownprotos()
-#define snmp_inc_ipindiscards()
-#define snmp_inc_ipindelivers()
-#define snmp_inc_ipoutrequests()
-#define snmp_inc_ipoutdiscards()
-#define snmp_inc_ipoutnoroutes()
-#define snmp_inc_ipreasmreqds()
-#define snmp_inc_ipreasmoks()
-#define snmp_inc_ipreasmfails()
-#define snmp_inc_ipfragoks()
-#define snmp_inc_ipfragfails()
-#define snmp_inc_ipfragcreates()
-#define snmp_inc_iproutingdiscards()
-#define snmp_insert_ipaddridx_tree(ni)
-#define snmp_delete_ipaddridx_tree(ni)
-#define snmp_insert_iprteidx_tree(dflt, ni)
-#define snmp_delete_iprteidx_tree(dflt, ni)
-
-/* ICMP */
-#define snmp_inc_icmpinmsgs()
-#define snmp_inc_icmpinerrors()
-#define snmp_inc_icmpindestunreachs()
-#define snmp_inc_icmpintimeexcds()
-#define snmp_inc_icmpinparmprobs()
-#define snmp_inc_icmpinsrcquenchs()
-#define snmp_inc_icmpinredirects()
-#define snmp_inc_icmpinechos()
-#define snmp_inc_icmpinechoreps()
-#define snmp_inc_icmpintimestamps()
-#define snmp_inc_icmpintimestampreps()
-#define snmp_inc_icmpinaddrmasks()
-#define snmp_inc_icmpinaddrmaskreps()
-#define snmp_inc_icmpoutmsgs()
-#define snmp_inc_icmpouterrors()
-#define snmp_inc_icmpoutdestunreachs()
-#define snmp_inc_icmpouttimeexcds()
-#define snmp_inc_icmpoutparmprobs()
-#define snmp_inc_icmpoutsrcquenchs()
-#define snmp_inc_icmpoutredirects()
-#define snmp_inc_icmpoutechos()
-#define snmp_inc_icmpoutechoreps()
-#define snmp_inc_icmpouttimestamps()
-#define snmp_inc_icmpouttimestampreps()
-#define snmp_inc_icmpoutaddrmasks()
-#define snmp_inc_icmpoutaddrmaskreps()
-/* TCP */
-#define snmp_inc_tcpactiveopens()
-#define snmp_inc_tcppassiveopens()
-#define snmp_inc_tcpattemptfails()
-#define snmp_inc_tcpestabresets()
-#define snmp_inc_tcpinsegs()
-#define snmp_inc_tcpoutsegs()
-#define snmp_inc_tcpretranssegs()
-#define snmp_inc_tcpinerrs()
-#define snmp_inc_tcpoutrsts()
-
-/* UDP */
-#define snmp_inc_udpindatagrams()
-#define snmp_inc_udpnoports()
-#define snmp_inc_udpinerrors()
-#define snmp_inc_udpoutdatagrams()
-#define snmp_insert_udpidx_tree(pcb)
-#define snmp_delete_udpidx_tree(pcb)
-
-/* SNMP */
-#define snmp_inc_snmpinpkts()
-#define snmp_inc_snmpoutpkts()
-#define snmp_inc_snmpinbadversions()
-#define snmp_inc_snmpinbadcommunitynames()
-#define snmp_inc_snmpinbadcommunityuses()
-#define snmp_inc_snmpinasnparseerrs()
-#define snmp_inc_snmpintoobigs()
-#define snmp_inc_snmpinnosuchnames()
-#define snmp_inc_snmpinbadvalues()
-#define snmp_inc_snmpinreadonlys()
-#define snmp_inc_snmpingenerrs()
-#define snmp_add_snmpintotalreqvars(value)
-#define snmp_add_snmpintotalsetvars(value)
-#define snmp_inc_snmpingetrequests()
-#define snmp_inc_snmpingetnexts()
-#define snmp_inc_snmpinsetrequests()
-#define snmp_inc_snmpingetresponses()
-#define snmp_inc_snmpintraps()
-#define snmp_inc_snmpouttoobigs()
-#define snmp_inc_snmpoutnosuchnames()
-#define snmp_inc_snmpoutbadvalues()
-#define snmp_inc_snmpoutgenerrs()
-#define snmp_inc_snmpoutgetrequests()
-#define snmp_inc_snmpoutgetnexts()
-#define snmp_inc_snmpoutsetrequests()
-#define snmp_inc_snmpoutgetresponses()
-#define snmp_inc_snmpouttraps()
-#define snmp_get_snmpgrpid_ptr(oid)
-#define snmp_set_snmpenableauthentraps(value)
-#define snmp_get_snmpenableauthentraps(value)
-
-#endif /* LWIP_SNMP */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_SNMP_H__ */
+++ /dev/null
-/**
- * @file
- * Abstract Syntax Notation One (ISO 8824, 8825) codec.
- */
-
-/*
- * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Christiaan Simons <christiaan.simons@axon.tv>
- */
-
-#ifndef __LWIP_SNMP_ASN1_H__
-#define __LWIP_SNMP_ASN1_H__
-
-#include "lwip/opt.h"
-#include "lwip/err.h"
-#include "lwip/pbuf.h"
-#include "lwip/snmp.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define SNMP_ASN1_UNIV (!0x80 | !0x40)
-#define SNMP_ASN1_APPLIC (!0x80 | 0x40)
-#define SNMP_ASN1_CONTXT ( 0x80 | !0x40)
-
-#define SNMP_ASN1_CONSTR (0x20)
-#define SNMP_ASN1_PRIMIT (!0x20)
-
-/* universal tags */
-#define SNMP_ASN1_INTEG 2
-#define SNMP_ASN1_OC_STR 4
-#define SNMP_ASN1_NUL 5
-#define SNMP_ASN1_OBJ_ID 6
-#define SNMP_ASN1_SEQ 16
-
-/* application specific (SNMP) tags */
-#define SNMP_ASN1_IPADDR 0 /* octet string size(4) */
-#define SNMP_ASN1_COUNTER 1 /* u32_t */
-#define SNMP_ASN1_GAUGE 2 /* u32_t */
-#define SNMP_ASN1_TIMETICKS 3 /* u32_t */
-#define SNMP_ASN1_OPAQUE 4 /* octet string */
-
-/* context specific (SNMP) tags */
-#define SNMP_ASN1_PDU_GET_REQ 0
-#define SNMP_ASN1_PDU_GET_NEXT_REQ 1
-#define SNMP_ASN1_PDU_GET_RESP 2
-#define SNMP_ASN1_PDU_SET_REQ 3
-#define SNMP_ASN1_PDU_TRAP 4
-
-err_t snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type);
-err_t snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length);
-err_t snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value);
-err_t snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value);
-err_t snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid);
-err_t snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw);
-
-void snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed);
-void snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed);
-void snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed);
-void snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed);
-err_t snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type);
-err_t snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length);
-err_t snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u8_t octets_needed, u32_t value);
-err_t snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u8_t octets_needed, s32_t value);
-err_t snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident);
-err_t snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u8_t raw_len, u8_t *raw);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_SNMP_ASN1_H__ */
+++ /dev/null
-/**
- * @file
- * SNMP Agent message handling structures.
- */
-
-/*
- * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Christiaan Simons <christiaan.simons@axon.tv>
- */
-
-#ifndef __LWIP_SNMP_MSG_H__
-#define __LWIP_SNMP_MSG_H__
-
-#include "lwip/opt.h"
-#include "lwip/snmp.h"
-#include "lwip/snmp_structs.h"
-
-#if SNMP_PRIVATE_MIB
-#include "private_mib.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* The listen port of the SNMP agent. Clients have to make their requests to
- this port. Most standard clients won't work if you change this! */
-#ifndef SNMP_IN_PORT
-#define SNMP_IN_PORT 161
-#endif
-/* The remote port the SNMP agent sends traps to. Most standard trap sinks won't
- work if you change this! */
-#ifndef SNMP_TRAP_PORT
-#define SNMP_TRAP_PORT 162
-#endif
-
-#define SNMP_ES_NOERROR 0
-#define SNMP_ES_TOOBIG 1
-#define SNMP_ES_NOSUCHNAME 2
-#define SNMP_ES_BADVALUE 3
-#define SNMP_ES_READONLY 4
-#define SNMP_ES_GENERROR 5
-
-#define SNMP_GENTRAP_COLDSTART 0
-#define SNMP_GENTRAP_WARMSTART 1
-#define SNMP_GENTRAP_AUTHFAIL 4
-#define SNMP_GENTRAP_ENTERPRISESPC 6
-
-struct snmp_varbind
-{
- /* next pointer, NULL for last in list */
- struct snmp_varbind *next;
- /* previous pointer, NULL for first in list */
- struct snmp_varbind *prev;
-
- /* object identifier length (in s32_t) */
- u8_t ident_len;
- /* object identifier array */
- s32_t *ident;
-
- /* object value ASN1 type */
- u8_t value_type;
- /* object value length (in u8_t) */
- u8_t value_len;
- /* object value */
- void *value;
-
- /* encoding varbind seq length length */
- u8_t seqlenlen;
- /* encoding object identifier length length */
- u8_t olenlen;
- /* encoding object value length length */
- u8_t vlenlen;
- /* encoding varbind seq length */
- u16_t seqlen;
- /* encoding object identifier length */
- u16_t olen;
- /* encoding object value length */
- u16_t vlen;
-};
-
-struct snmp_varbind_root
-{
- struct snmp_varbind *head;
- struct snmp_varbind *tail;
- /* number of variable bindings in list */
- u8_t count;
- /* encoding varbind-list seq length length */
- u8_t seqlenlen;
- /* encoding varbind-list seq length */
- u16_t seqlen;
-};
-
-/** output response message header length fields */
-struct snmp_resp_header_lengths
-{
- /* encoding error-index length length */
- u8_t erridxlenlen;
- /* encoding error-status length length */
- u8_t errstatlenlen;
- /* encoding request id length length */
- u8_t ridlenlen;
- /* encoding pdu length length */
- u8_t pdulenlen;
- /* encoding community length length */
- u8_t comlenlen;
- /* encoding version length length */
- u8_t verlenlen;
- /* encoding sequence length length */
- u8_t seqlenlen;
-
- /* encoding error-index length */
- u16_t erridxlen;
- /* encoding error-status length */
- u16_t errstatlen;
- /* encoding request id length */
- u16_t ridlen;
- /* encoding pdu length */
- u16_t pdulen;
- /* encoding community length */
- u16_t comlen;
- /* encoding version length */
- u16_t verlen;
- /* encoding sequence length */
- u16_t seqlen;
-};
-
-/** output response message header length fields */
-struct snmp_trap_header_lengths
-{
- /* encoding timestamp length length */
- u8_t tslenlen;
- /* encoding specific-trap length length */
- u8_t strplenlen;
- /* encoding generic-trap length length */
- u8_t gtrplenlen;
- /* encoding agent-addr length length */
- u8_t aaddrlenlen;
- /* encoding enterprise-id length length */
- u8_t eidlenlen;
- /* encoding pdu length length */
- u8_t pdulenlen;
- /* encoding community length length */
- u8_t comlenlen;
- /* encoding version length length */
- u8_t verlenlen;
- /* encoding sequence length length */
- u8_t seqlenlen;
-
- /* encoding timestamp length */
- u16_t tslen;
- /* encoding specific-trap length */
- u16_t strplen;
- /* encoding generic-trap length */
- u16_t gtrplen;
- /* encoding agent-addr length */
- u16_t aaddrlen;
- /* encoding enterprise-id length */
- u16_t eidlen;
- /* encoding pdu length */
- u16_t pdulen;
- /* encoding community length */
- u16_t comlen;
- /* encoding version length */
- u16_t verlen;
- /* encoding sequence length */
- u16_t seqlen;
-};
-
-/* Accepting new SNMP messages. */
-#define SNMP_MSG_EMPTY 0
-/* Search for matching object for variable binding. */
-#define SNMP_MSG_SEARCH_OBJ 1
-/* Perform SNMP operation on in-memory object.
- Pass-through states, for symmetry only. */
-#define SNMP_MSG_INTERNAL_GET_OBJDEF 2
-#define SNMP_MSG_INTERNAL_GET_VALUE 3
-#define SNMP_MSG_INTERNAL_SET_TEST 4
-#define SNMP_MSG_INTERNAL_GET_OBJDEF_S 5
-#define SNMP_MSG_INTERNAL_SET_VALUE 6
-/* Perform SNMP operation on object located externally.
- In theory this could be used for building a proxy agent.
- Practical use is for an enterprise spc. app. gateway. */
-#define SNMP_MSG_EXTERNAL_GET_OBJDEF 7
-#define SNMP_MSG_EXTERNAL_GET_VALUE 8
-#define SNMP_MSG_EXTERNAL_SET_TEST 9
-#define SNMP_MSG_EXTERNAL_GET_OBJDEF_S 10
-#define SNMP_MSG_EXTERNAL_SET_VALUE 11
-
-#define SNMP_COMMUNITY_STR_LEN 64
-struct snmp_msg_pstat
-{
- /* lwIP local port (161) binding */
- struct udp_pcb *pcb;
- /* source IP address */
- struct ip_addr sip;
- /* source UDP port */
- u16_t sp;
- /* request type */
- u8_t rt;
- /* request ID */
- s32_t rid;
- /* error status */
- s32_t error_status;
- /* error index */
- s32_t error_index;
- /* community name (zero terminated) */
- u8_t community[SNMP_COMMUNITY_STR_LEN + 1];
- /* community string length (exclusive zero term) */
- u8_t com_strlen;
- /* one out of MSG_EMPTY, MSG_DEMUX, MSG_INTERNAL, MSG_EXTERNAL_x */
- u8_t state;
- /* saved arguments for MSG_EXTERNAL_x */
- struct mib_external_node *ext_mib_node;
- struct snmp_name_ptr ext_name_ptr;
- struct obj_def ext_object_def;
- struct snmp_obj_id ext_oid;
- /* index into input variable binding list */
- u8_t vb_idx;
- /* ptr into input variable binding list */
- struct snmp_varbind *vb_ptr;
- /* list of variable bindings from input */
- struct snmp_varbind_root invb;
- /* list of variable bindings to output */
- struct snmp_varbind_root outvb;
- /* output response lengths used in ASN encoding */
- struct snmp_resp_header_lengths rhl;
-};
-
-struct snmp_msg_trap
-{
- /* lwIP local port (161) binding */
- struct udp_pcb *pcb;
- /* destination IP address in network order */
- struct ip_addr dip;
-
- /* source enterprise ID (sysObjectID) */
- struct snmp_obj_id *enterprise;
- /* source IP address, raw network order format */
- u8_t sip_raw[4];
- /* generic trap code */
- u32_t gen_trap;
- /* specific trap code */
- u32_t spc_trap;
- /* timestamp */
- u32_t ts;
- /* list of variable bindings to output */
- struct snmp_varbind_root outvb;
- /* output trap lengths used in ASN encoding */
- struct snmp_trap_header_lengths thl;
-};
-
-/** Agent Version constant, 0 = v1 oddity */
-extern const s32_t snmp_version;
-/** Agent default "public" community string */
-extern const char snmp_publiccommunity[7];
-
-extern struct snmp_msg_trap trap_msg;
-
-/** Agent setup, start listening to port 161. */
-void snmp_init(void);
-void snmp_trap_dst_enable(u8_t dst_idx, u8_t enable);
-void snmp_trap_dst_ip_set(u8_t dst_idx, struct ip_addr *dst);
-
-/** Varbind-list functions. */
-struct snmp_varbind* snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len);
-void snmp_varbind_free(struct snmp_varbind *vb);
-void snmp_varbind_list_free(struct snmp_varbind_root *root);
-void snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb);
-struct snmp_varbind* snmp_varbind_tail_remove(struct snmp_varbind_root *root);
-
-/** Handle an internal (recv) or external (private response) event. */
-void snmp_msg_event(u8_t request_id);
-err_t snmp_send_response(struct snmp_msg_pstat *m_stat);
-err_t snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap);
-void snmp_coldstart_trap(void);
-void snmp_authfail_trap(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_SNMP_MSG_H__ */
+++ /dev/null
-/**
- * @file
- * Generic MIB tree structures.
- *
- * @todo namespace prefixes
- */
-
-/*
- * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Christiaan Simons <christiaan.simons@axon.tv>
- */
-
-#ifndef __LWIP_SNMP_STRUCTS_H__
-#define __LWIP_SNMP_STRUCTS_H__
-
-#include "lwip/opt.h"
-
-#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/snmp.h"
-
-#if SNMP_PRIVATE_MIB
-#include "private_mib.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* MIB object instance */
-#define MIB_OBJECT_NONE 0
-#define MIB_OBJECT_SCALAR 1
-#define MIB_OBJECT_TAB 2
-
-/* MIB object access */
-#define MIB_OBJECT_READ_ONLY 0
-#define MIB_OBJECT_READ_WRITE 1
-#define MIB_OBJECT_WRITE_ONLY 2
-#define MIB_OBJECT_NOT_ACCESSIBLE 3
-
-/** object definition returned by (get_object_def)() */
-struct obj_def
-{
- /* MIB_OBJECT_NONE (0), MIB_OBJECT_SCALAR (1), MIB_OBJECT_TAB (2) */
- u8_t instance;
- /* 0 read-only, 1 read-write, 2 write-only, 3 not-accessible */
- u8_t access;
- /* ASN type for this object */
- u8_t asn_type;
- /* value length (host length) */
- u16_t v_len;
- /* length of instance part of supplied object identifier */
- u8_t id_inst_len;
- /* instance part of supplied object identifier */
- s32_t *id_inst_ptr;
-};
-
-struct snmp_name_ptr
-{
- u8_t ident_len;
- s32_t *ident;
-};
-
-/** MIB const scalar (.0) node */
-#define MIB_NODE_SC 0x01
-/** MIB const array node */
-#define MIB_NODE_AR 0x02
-/** MIB array node (mem_malloced from RAM) */
-#define MIB_NODE_RA 0x03
-/** MIB list root node (mem_malloced from RAM) */
-#define MIB_NODE_LR 0x04
-/** MIB node for external objects */
-#define MIB_NODE_EX 0x05
-
-/** node "base class" layout, the mandatory fields for a node */
-struct mib_node
-{
- /** returns struct obj_def for the given object identifier */
- void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
- /** returns object value for the given object identifier,
- @note the caller must allocate at least len bytes for the value */
- void (*get_value)(struct obj_def *od, u16_t len, void *value);
- /** tests length and/or range BEFORE setting */
- u8_t (*set_test)(struct obj_def *od, u16_t len, void *value);
- /** sets object value, only to be called when set_test() */
- void (*set_value)(struct obj_def *od, u16_t len, void *value);
- /** One out of MIB_NODE_AR, MIB_NODE_LR or MIB_NODE_EX */
- const u8_t node_type;
- /* array or max list length */
- const u16_t maxlength;
-};
-
-/** derived node for scalars .0 index */
-typedef struct mib_node mib_scalar_node;
-
-/** derived node, points to a fixed size const array
- of sub-identifiers plus a 'child' pointer */
-struct mib_array_node
-{
- /* inherited "base class" members */
- void (* const get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
- void (* const get_value)(struct obj_def *od, u16_t len, void *value);
- u8_t (*set_test)(struct obj_def *od, u16_t len, void *value);
- void (*set_value)(struct obj_def *od, u16_t len, void *value);
-
- const u8_t node_type;
- const u16_t maxlength;
-
- /* aditional struct members */
- const s32_t *objid;
- struct mib_node* const *nptr;
-};
-
-/** derived node, points to a fixed size mem_malloced array
- of sub-identifiers plus a 'child' pointer */
-struct mib_ram_array_node
-{
- /* inherited "base class" members */
- void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
- void (*get_value)(struct obj_def *od, u16_t len, void *value);
- u8_t (*set_test)(struct obj_def *od, u16_t len, void *value);
- void (*set_value)(struct obj_def *od, u16_t len, void *value);
-
- u8_t node_type;
- u16_t maxlength;
-
- /* aditional struct members */
- s32_t *objid;
- struct mib_node **nptr;
-};
-
-struct mib_list_node
-{
- struct mib_list_node *prev;
- struct mib_list_node *next;
- s32_t objid;
- struct mib_node *nptr;
-};
-
-/** derived node, points to a doubly linked list
- of sub-identifiers plus a 'child' pointer */
-struct mib_list_rootnode
-{
- /* inherited "base class" members */
- void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
- void (*get_value)(struct obj_def *od, u16_t len, void *value);
- u8_t (*set_test)(struct obj_def *od, u16_t len, void *value);
- void (*set_value)(struct obj_def *od, u16_t len, void *value);
-
- u8_t node_type;
- u16_t maxlength;
-
- /* aditional struct members */
- struct mib_list_node *head;
- struct mib_list_node *tail;
- /* counts list nodes in list */
- u16_t count;
-};
-
-/** derived node, has access functions for mib object in external memory or device
- using 'tree_level' and 'idx', with a range 0 .. (level_length() - 1) */
-struct mib_external_node
-{
- /* inherited "base class" members */
- void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
- void (*get_value)(struct obj_def *od, u16_t len, void *value);
- u8_t (*set_test)(struct obj_def *od, u16_t len, void *value);
- void (*set_value)(struct obj_def *od, u16_t len, void *value);
-
- u8_t node_type;
- u16_t maxlength;
-
- /* aditional struct members */
- /** points to an extenal (in memory) record of some sort of addressing
- information, passed to and interpreted by the funtions below */
- void* addr_inf;
- /** tree levels under this node */
- u8_t tree_levels;
- /** number of objects at this level */
- u16_t (*level_length)(void* addr_inf, u8_t level);
- /** compares object sub identifier with external id
- return zero when equal, nonzero when unequal */
- s32_t (*ident_cmp)(void* addr_inf, u8_t level, u16_t idx, s32_t sub_id);
- void (*get_objid)(void* addr_inf, u8_t level, u16_t idx, s32_t *sub_id);
-
- /** async Questions */
- void (*get_object_def_q)(void* addr_inf, u8_t rid, u8_t ident_len, s32_t *ident);
- void (*get_value_q)(u8_t rid, struct obj_def *od);
- void (*set_test_q)(u8_t rid, struct obj_def *od);
- void (*set_value_q)(u8_t rid, struct obj_def *od, u16_t len, void *value);
- /** async Answers */
- void (*get_object_def_a)(u8_t rid, u8_t ident_len, s32_t *ident, struct obj_def *od);
- void (*get_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value);
- u8_t (*set_test_a)(u8_t rid, struct obj_def *od, u16_t len, void *value);
- void (*set_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value);
- /** async Panic Close (agent returns error reply,
- e.g. used for external transaction cleanup) */
- void (*get_object_def_pc)(u8_t rid, u8_t ident_len, s32_t *ident);
- void (*get_value_pc)(u8_t rid, struct obj_def *od);
- void (*set_test_pc)(u8_t rid, struct obj_def *od);
- void (*set_value_pc)(u8_t rid, struct obj_def *od);
-};
-
-/** export MIB tree from mib2.c */
-extern const struct mib_array_node internet;
-
-/** dummy function pointers for non-leaf MIB nodes from mib2.c */
-void noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
-void noleafs_get_value(struct obj_def *od, u16_t len, void *value);
-u8_t noleafs_set_test(struct obj_def *od, u16_t len, void *value);
-void noleafs_set_value(struct obj_def *od, u16_t len, void *value);
-
-void snmp_oidtoip(s32_t *ident, struct ip_addr *ip);
-void snmp_iptooid(struct ip_addr *ip, s32_t *ident);
-void snmp_ifindextonetif(s32_t ifindex, struct netif **netif);
-void snmp_netiftoifindex(struct netif *netif, s32_t *ifidx);
-
-struct mib_list_node* snmp_mib_ln_alloc(s32_t id);
-void snmp_mib_ln_free(struct mib_list_node *ln);
-struct mib_list_rootnode* snmp_mib_lrn_alloc(void);
-void snmp_mib_lrn_free(struct mib_list_rootnode *lrn);
-
-s8_t snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn);
-s8_t snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn);
-struct mib_list_rootnode *snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n);
-
-struct mib_node* snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np);
-struct mib_node* snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret);
-u8_t snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident);
-u8_t snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_SNMP */
-
-#endif /* __LWIP_SNMP_STRUCTS_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_STATS_H__
-#define __LWIP_STATS_H__
-
-#include "lwip/opt.h"
-
-#include "lwip/mem.h"
-#include "lwip/memp.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if LWIP_STATS
-
-#ifndef LWIP_STATS_LARGE
-#define LWIP_STATS_LARGE 0
-#endif
-
-#if LWIP_STATS_LARGE
-#define STAT_COUNTER u32_t
-#define STAT_COUNTER_F U32_F
-#else
-#define STAT_COUNTER u16_t
-#define STAT_COUNTER_F U16_F
-#endif
-
-struct stats_proto {
- STAT_COUNTER xmit; /* Transmitted packets. */
- STAT_COUNTER rexmit; /* Retransmitted packets. */
- STAT_COUNTER recv; /* Received packets. */
- STAT_COUNTER fw; /* Forwarded packets. */
- STAT_COUNTER drop; /* Dropped packets. */
- STAT_COUNTER chkerr; /* Checksum error. */
- STAT_COUNTER lenerr; /* Invalid length error. */
- STAT_COUNTER memerr; /* Out of memory error. */
- STAT_COUNTER rterr; /* Routing error. */
- STAT_COUNTER proterr; /* Protocol error. */
- STAT_COUNTER opterr; /* Error in options. */
- STAT_COUNTER err; /* Misc error. */
- STAT_COUNTER cachehit;
-};
-
-struct stats_igmp {
- STAT_COUNTER lenerr; /* Invalid length error. */
- STAT_COUNTER chkerr; /* Checksum error. */
- STAT_COUNTER v1_rxed; /* */
- STAT_COUNTER join_sent; /* */
- STAT_COUNTER leave_sent; /* */
- STAT_COUNTER unicast_query; /* */
- STAT_COUNTER report_sent; /* */
- STAT_COUNTER report_rxed; /* */
- STAT_COUNTER group_query_rxed; /* */
-};
-
-struct stats_mem {
- mem_size_t avail;
- mem_size_t used;
- mem_size_t max;
- mem_size_t err;
-};
-
-struct stats_syselem {
- STAT_COUNTER used;
- STAT_COUNTER max;
- STAT_COUNTER err;
-};
-
-struct stats_sys {
- struct stats_syselem sem;
- struct stats_syselem mbox;
-};
-
-struct stats_ {
-#if LINK_STATS
- struct stats_proto link;
-#endif
-#if ETHARP_STATS
- struct stats_proto etharp;
-#endif
-#if IPFRAG_STATS
- struct stats_proto ip_frag;
-#endif
-#if IP_STATS
- struct stats_proto ip;
-#endif
-#if ICMP_STATS
- struct stats_proto icmp;
-#endif
-#if IGMP_STATS
- struct stats_igmp igmp;
-#endif
-#if UDP_STATS
- struct stats_proto udp;
-#endif
-#if TCP_STATS
- struct stats_proto tcp;
-#endif
-#if MEM_STATS
- struct stats_mem mem;
-#endif
-#if MEMP_STATS
- struct stats_mem memp[MEMP_MAX];
-#endif
-#if SYS_STATS
- struct stats_sys sys;
-#endif
-};
-
-extern struct stats_ lwip_stats;
-
-#define stats_init() /* Compatibility define, not init needed. */
-
-#define STATS_INC(x) ++lwip_stats.x
-#else
-#define stats_init()
-#define STATS_INC(x)
-#endif /* LWIP_STATS */
-
-#if TCP_STATS
-#define TCP_STATS_INC(x) STATS_INC(x)
-#else
-#define TCP_STATS_INC(x)
-#endif
-
-#if UDP_STATS
-#define UDP_STATS_INC(x) STATS_INC(x)
-#else
-#define UDP_STATS_INC(x)
-#endif
-
-#if ICMP_STATS
-#define ICMP_STATS_INC(x) STATS_INC(x)
-#else
-#define ICMP_STATS_INC(x)
-#endif
-
-#if IGMP_STATS
-#define IGMP_STATS_INC(x) STATS_INC(x)
-#else
-#define IGMP_STATS_INC(x)
-#endif
-
-#if IP_STATS
-#define IP_STATS_INC(x) STATS_INC(x)
-#else
-#define IP_STATS_INC(x)
-#endif
-
-#if IPFRAG_STATS
-#define IPFRAG_STATS_INC(x) STATS_INC(x)
-#else
-#define IPFRAG_STATS_INC(x)
-#endif
-
-#if ETHARP_STATS
-#define ETHARP_STATS_INC(x) STATS_INC(x)
-#else
-#define ETHARP_STATS_INC(x)
-#endif
-
-#if LINK_STATS
-#define LINK_STATS_INC(x) STATS_INC(x)
-#else
-#define LINK_STATS_INC(x)
-#endif
-
-/* Display of statistics */
-#if LWIP_STATS_DISPLAY
-void stats_display(void);
-#else
-#define stats_display()
-#endif /* LWIP_STATS_DISPLAY */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_STATS_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_SYS_H__
-#define __LWIP_SYS_H__
-
-#include "lwip/opt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if NO_SYS
-
-/* For a totally minimal and standalone system, we provide null
- definitions of the sys_ functions. */
-typedef u8_t sys_sem_t;
-typedef u8_t sys_mbox_t;
-typedef u8_t sys_prot_t;
-struct sys_timeo {u8_t dummy;};
-
-#define sys_init()
-#define sys_timeout(m,h,a)
-#define sys_untimeout(m,a)
-#define sys_sem_new(c) c
-#define sys_sem_signal(s)
-#define sys_sem_wait(s)
-#define sys_sem_wait_timeout(s,t)
-#define sys_arch_sem_wait(s,t)
-#define sys_sem_free(s)
-#define sys_mbox_new(s) 0
-#define sys_mbox_fetch(m,d)
-#define sys_mbox_tryfetch(m,d)
-#define sys_mbox_post(m,d)
-#define sys_mbox_trypost(m,d)
-#define sys_mbox_free(m)
-
-#define sys_thread_new(n,t,a,s,p)
-
-#else /* NO_SYS */
-
-/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */
-#define SYS_ARCH_TIMEOUT 0xffffffffUL
-
-/* sys_mbox_tryfetch returns SYS_MBOX_EMPTY if appropriate.
- * For now we use the same magic value, but we allow this to change in future.
- */
-#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT
-
-#include "lwip/err.h"
-#include "arch/sys_arch.h"
-
-typedef void (* sys_timeout_handler)(void *arg);
-
-struct sys_timeo {
- struct sys_timeo *next;
- u32_t time;
- sys_timeout_handler h;
- void *arg;
-};
-
-struct sys_timeouts {
- struct sys_timeo *next;
-};
-
-/* sys_init() must be called before anthing else. */
-void sys_init(void);
-
-/*
- * sys_timeout():
- *
- * Schedule a timeout a specified amount of milliseconds in the
- * future. When the timeout occurs, the specified timeout handler will
- * be called. The handler will be passed the "arg" argument when
- * called.
- *
- */
-void sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg);
-void sys_untimeout(sys_timeout_handler h, void *arg);
-struct sys_timeouts *sys_arch_timeouts(void);
-
-/* Semaphore functions. */
-sys_sem_t sys_sem_new(u8_t count);
-void sys_sem_signal(sys_sem_t sem);
-u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout);
-void sys_sem_free(sys_sem_t sem);
-void sys_sem_wait(sys_sem_t sem);
-int sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout);
-
-/* Time functions. */
-#ifndef sys_msleep
-void sys_msleep(u32_t ms); /* only has a (close to) 1 jiffy resolution. */
-#endif
-#ifndef sys_jiffies
-u32_t sys_jiffies(void); /* since power up. */
-#endif
-
-/* Mailbox functions. */
-sys_mbox_t sys_mbox_new(int size);
-void sys_mbox_post(sys_mbox_t mbox, void *msg);
-err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg);
-u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout);
-#ifndef sys_arch_mbox_tryfetch /* Allow port to override with a macro */
-u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg);
-#endif
-/* For now, we map straight to sys_arch implementation. */
-#define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg)
-void sys_mbox_free(sys_mbox_t mbox);
-void sys_mbox_fetch(sys_mbox_t mbox, void **msg);
-
-/* Thread functions. */
-sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio);
-
-/* The following functions are used only in Unix code, and
- can be omitted when porting the stack. */
-/* Returns the current time in microseconds. */
-unsigned long sys_now(void);
-
-#endif /* NO_SYS */
-
-/* Critical Region Protection */
-/* These functions must be implemented in the sys_arch.c file.
- In some implementations they can provide a more light-weight protection
- mechanism than using semaphores. Otherwise semaphores can be used for
- implementation */
-#ifndef SYS_ARCH_PROTECT
-/** SYS_LIGHTWEIGHT_PROT
- * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
- * for certain critical regions during buffer allocation, deallocation and memory
- * allocation and deallocation.
- */
-#if SYS_LIGHTWEIGHT_PROT
-
-/** SYS_ARCH_DECL_PROTECT
- * declare a protection variable. This macro will default to defining a variable of
- * type sys_prot_t. If a particular port needs a different implementation, then
- * this macro may be defined in sys_arch.h.
- */
-#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev
-/** SYS_ARCH_PROTECT
- * Perform a "fast" protect. This could be implemented by
- * disabling interrupts for an embedded system or by using a semaphore or
- * mutex. The implementation should allow calling SYS_ARCH_PROTECT when
- * already protected. The old protection level is returned in the variable
- * "lev". This macro will default to calling the sys_arch_protect() function
- * which should be implemented in sys_arch.c. If a particular port needs a
- * different implementation, then this macro may be defined in sys_arch.h
- */
-#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect()
-/** SYS_ARCH_UNPROTECT
- * Perform a "fast" set of the protection level to "lev". This could be
- * implemented by setting the interrupt level to "lev" within the MACRO or by
- * using a semaphore or mutex. This macro will default to calling the
- * sys_arch_unprotect() function which should be implemented in
- * sys_arch.c. If a particular port needs a different implementation, then
- * this macro may be defined in sys_arch.h
- */
-#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev)
-sys_prot_t sys_arch_protect(void);
-void sys_arch_unprotect(sys_prot_t pval);
-
-#else
-
-#define SYS_ARCH_DECL_PROTECT(lev)
-#define SYS_ARCH_PROTECT(lev)
-#define SYS_ARCH_UNPROTECT(lev)
-
-#endif /* SYS_LIGHTWEIGHT_PROT */
-
-#endif /* SYS_ARCH_PROTECT */
-
-/*
- * Macros to set/get and increase/decrease variables in a thread-safe way.
- * Use these for accessing variable that are used from more than one thread.
- */
-
-#ifndef SYS_ARCH_INC
-#define SYS_ARCH_INC(var, val) do { \
- SYS_ARCH_DECL_PROTECT(old_level); \
- SYS_ARCH_PROTECT(old_level); \
- var += val; \
- SYS_ARCH_UNPROTECT(old_level); \
- } while(0)
-#endif /* SYS_ARCH_INC */
-
-#ifndef SYS_ARCH_DEC
-#define SYS_ARCH_DEC(var, val) do { \
- SYS_ARCH_DECL_PROTECT(old_level); \
- SYS_ARCH_PROTECT(old_level); \
- var -= val; \
- SYS_ARCH_UNPROTECT(old_level); \
- } while(0)
-#endif /* SYS_ARCH_DEC */
-
-#ifndef SYS_ARCH_GET
-#define SYS_ARCH_GET(var, ret) do { \
- SYS_ARCH_DECL_PROTECT(old_level); \
- SYS_ARCH_PROTECT(old_level); \
- ret = var; \
- SYS_ARCH_UNPROTECT(old_level); \
- } while(0)
-#endif /* SYS_ARCH_GET */
-
-#ifndef SYS_ARCH_SET
-#define SYS_ARCH_SET(var, val) do { \
- SYS_ARCH_DECL_PROTECT(old_level); \
- SYS_ARCH_PROTECT(old_level); \
- var = val; \
- SYS_ARCH_UNPROTECT(old_level); \
- } while(0)
-#endif /* SYS_ARCH_SET */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_SYS_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_TCP_H__
-#define __LWIP_TCP_H__
-
-#include "lwip/opt.h"
-
-#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/sys.h"
-#include "lwip/mem.h"
-#include "lwip/pbuf.h"
-#include "lwip/ip.h"
-#include "lwip/icmp.h"
-#include "lwip/err.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct tcp_pcb;
-
-/* Functions for interfacing with TCP: */
-
-/* Lower layer interface to TCP: */
-#define tcp_init() /* Compatibility define, not init needed. */
-void tcp_tmr (void); /* Must be called every
- TCP_TMR_INTERVAL
- ms. (Typically 250 ms). */
-/* Application program's interface: */
-struct tcp_pcb * tcp_new (void);
-struct tcp_pcb * tcp_alloc (u8_t prio);
-
-void tcp_arg (struct tcp_pcb *pcb, void *arg);
-void tcp_accept (struct tcp_pcb *pcb,
- err_t (* accept)(void *arg, struct tcp_pcb *newpcb,
- err_t err));
-void tcp_recv (struct tcp_pcb *pcb,
- err_t (* recv)(void *arg, struct tcp_pcb *tpcb,
- struct pbuf *p, err_t err));
-void tcp_sent (struct tcp_pcb *pcb,
- err_t (* sent)(void *arg, struct tcp_pcb *tpcb,
- u16_t len));
-void tcp_poll (struct tcp_pcb *pcb,
- err_t (* poll)(void *arg, struct tcp_pcb *tpcb),
- u8_t interval);
-void tcp_err (struct tcp_pcb *pcb,
- void (* err)(void *arg, err_t err));
-
-#define tcp_mss(pcb) ((pcb)->mss)
-#define tcp_sndbuf(pcb) ((pcb)->snd_buf)
-
-#if TCP_LISTEN_BACKLOG
-#define tcp_accepted(pcb) (((struct tcp_pcb_listen *)(pcb))->accepts_pending--)
-#else /* TCP_LISTEN_BACKLOG */
-#define tcp_accepted(pcb)
-#endif /* TCP_LISTEN_BACKLOG */
-
-void tcp_recved (struct tcp_pcb *pcb, u16_t len);
-err_t tcp_bind (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
- u16_t port);
-err_t tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
- u16_t port, err_t (* connected)(void *arg,
- struct tcp_pcb *tpcb,
- err_t err));
-
-struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog);
-#define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG)
-
-void tcp_abort (struct tcp_pcb *pcb);
-err_t tcp_close (struct tcp_pcb *pcb);
-
-/* Flags for "apiflags" parameter in tcp_write and tcp_enqueue */
-#define TCP_WRITE_FLAG_COPY 0x01
-#define TCP_WRITE_FLAG_MORE 0x02
-
-err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len,
- u8_t apiflags);
-
-void tcp_setprio (struct tcp_pcb *pcb, u8_t prio);
-
-#define TCP_PRIO_MIN 1
-#define TCP_PRIO_NORMAL 64
-#define TCP_PRIO_MAX 127
-
-/* It is also possible to call these two functions at the right
- intervals (instead of calling tcp_tmr()). */
-void tcp_slowtmr (void);
-void tcp_fasttmr (void);
-
-
-/* Only used by IP to pass a TCP segment to TCP: */
-void tcp_input (struct pbuf *p, struct netif *inp);
-/* Used within the TCP code only: */
-err_t tcp_output (struct tcp_pcb *pcb);
-void tcp_rexmit (struct tcp_pcb *pcb);
-void tcp_rexmit_rto (struct tcp_pcb *pcb);
-
-/**
- * This is the Nagle algorithm: inhibit the sending of new TCP
- * segments when new outgoing data arrives from the user if any
- * previously transmitted data on the connection remains
- * unacknowledged.
- */
-#define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \
- ((tpcb)->flags & TF_NODELAY) || \
- (((tpcb)->unsent != NULL) && ((tpcb)->unsent->next != NULL))) ? \
- 1 : 0)
-#define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK)
-
-
-/** This returns a TCP header option for MSS in an u32_t */
-#define TCP_BUILD_MSS_OPTION() htonl(((u32_t)2 << 24) | \
- ((u32_t)4 << 16) | \
- (((u32_t)TCP_MSS / 256) << 8) | \
- (TCP_MSS & 255))
-
-#define TCP_SEQ_LT(a,b) ((s32_t)((a)-(b)) < 0)
-#define TCP_SEQ_LEQ(a,b) ((s32_t)((a)-(b)) <= 0)
-#define TCP_SEQ_GT(a,b) ((s32_t)((a)-(b)) > 0)
-#define TCP_SEQ_GEQ(a,b) ((s32_t)((a)-(b)) >= 0)
-/* is b<=a<=c? */
-#if 0 /* see bug #10548 */
-#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b))
-#endif
-#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c))
-#define TCP_FIN 0x01U
-#define TCP_SYN 0x02U
-#define TCP_RST 0x04U
-#define TCP_PSH 0x08U
-#define TCP_ACK 0x10U
-#define TCP_URG 0x20U
-#define TCP_ECE 0x40U
-#define TCP_CWR 0x80U
-
-#define TCP_FLAGS 0x3fU
-
-/* Length of the TCP header, excluding options. */
-#define TCP_HLEN 20
-
-#ifndef TCP_TMR_INTERVAL
-#define TCP_TMR_INTERVAL 250 /* The TCP timer interval in milliseconds. */
-#endif /* TCP_TMR_INTERVAL */
-
-#ifndef TCP_FAST_INTERVAL
-#define TCP_FAST_INTERVAL TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */
-#endif /* TCP_FAST_INTERVAL */
-
-#ifndef TCP_SLOW_INTERVAL
-#define TCP_SLOW_INTERVAL (2*TCP_TMR_INTERVAL) /* the coarse grained timeout in milliseconds */
-#endif /* TCP_SLOW_INTERVAL */
-
-#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */
-#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */
-
-#define TCP_OOSEQ_TIMEOUT 6U /* x RTO */
-
-#ifndef TCP_MSL
-#define TCP_MSL 60000U /* The maximum segment lifetime in milliseconds */
-#endif
-
-/* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */
-#ifndef TCP_KEEPIDLE_DEFAULT
-#define TCP_KEEPIDLE_DEFAULT 7200000UL /* Default KEEPALIVE timer in milliseconds */
-#endif
-
-#ifndef TCP_KEEPINTVL_DEFAULT
-#define TCP_KEEPINTVL_DEFAULT 75000UL /* Default Time between KEEPALIVE probes in milliseconds */
-#endif
-
-#ifndef TCP_KEEPCNT_DEFAULT
-#define TCP_KEEPCNT_DEFAULT 9U /* Default Counter for KEEPALIVE probes */
-#endif
-
-#define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */
-
-/* Fields are (of course) in network byte order.
- * Some fields are converted to host byte order in tcp_input().
- */
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct tcp_hdr {
- PACK_STRUCT_FIELD(u16_t src);
- PACK_STRUCT_FIELD(u16_t dest);
- PACK_STRUCT_FIELD(u32_t seqno);
- PACK_STRUCT_FIELD(u32_t ackno);
- PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);
- PACK_STRUCT_FIELD(u16_t wnd);
- PACK_STRUCT_FIELD(u16_t chksum);
- PACK_STRUCT_FIELD(u16_t urgp);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-#define TCPH_OFFSET(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 8)
-#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)
-#define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)
-
-#define TCPH_OFFSET_SET(phdr, offset) (phdr)->_hdrlen_rsvd_flags = htons(((offset) << 8) | TCPH_FLAGS(phdr))
-#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr))
-#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons((ntohs((phdr)->_hdrlen_rsvd_flags) & ~TCP_FLAGS) | (flags))
-#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (flags))
-#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) )
-
-#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & TCP_FIN || \
- TCPH_FLAGS((seg)->tcphdr) & TCP_SYN)? 1: 0))
-
-enum tcp_state {
- CLOSED = 0,
- LISTEN = 1,
- SYN_SENT = 2,
- SYN_RCVD = 3,
- ESTABLISHED = 4,
- FIN_WAIT_1 = 5,
- FIN_WAIT_2 = 6,
- CLOSE_WAIT = 7,
- CLOSING = 8,
- LAST_ACK = 9,
- TIME_WAIT = 10
-};
-
-/** Flags used on input processing, not on pcb->flags
-*/
-#define TF_RESET (u8_t)0x08U /* Connection was reset. */
-#define TF_CLOSED (u8_t)0x10U /* Connection was sucessfully closed. */
-#define TF_GOT_FIN (u8_t)0x20U /* Connection was closed by the remote end. */
-
-/**
- * members common to struct tcp_pcb and struct tcp_listen_pcb
- */
-#define TCP_PCB_COMMON(type) \
- type *next; /* for the linked list */ \
- enum tcp_state state; /* TCP state */ \
- u8_t prio; \
- void *callback_arg; \
- /* ports are in host byte order */ \
- u16_t local_port
-
-/* the TCP protocol control block */
-struct tcp_pcb {
-/** common PCB members */
- IP_PCB;
-/** protocol specific PCB members */
- TCP_PCB_COMMON(struct tcp_pcb);
-
- /* ports are in host byte order */
- u16_t remote_port;
-
- u8_t flags;
-#define TF_ACK_DELAY (u8_t)0x01U /* Delayed ACK. */
-#define TF_ACK_NOW (u8_t)0x02U /* Immediate ACK. */
-#define TF_INFR (u8_t)0x04U /* In fast recovery. */
-#define TF_FIN (u8_t)0x20U /* Connection was closed locally (FIN segment enqueued). */
-#define TF_NODELAY (u8_t)0x40U /* Disable Nagle algorithm */
-#define TF_NAGLEMEMERR (u8_t)0x80U /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */
-
- /* the rest of the fields are in host byte order
- as we have to do some math with them */
- /* receiver variables */
- u32_t rcv_nxt; /* next seqno expected */
- u16_t rcv_wnd; /* receiver window */
- u16_t rcv_ann_wnd; /* announced receive window */
-
- /* Timers */
- u32_t tmr;
- u8_t polltmr, pollinterval;
-
- /* Retransmission timer. */
- s16_t rtime;
-
- u16_t mss; /* maximum segment size */
-
- /* RTT (round trip time) estimation variables */
- u32_t rttest; /* RTT estimate in 500ms ticks */
- u32_t rtseq; /* sequence number being timed */
- s16_t sa, sv; /* @todo document this */
-
- s16_t rto; /* retransmission time-out */
- u8_t nrtx; /* number of retransmissions */
-
- /* fast retransmit/recovery */
- u32_t lastack; /* Highest acknowledged seqno. */
- u8_t dupacks;
-
- /* congestion avoidance/control variables */
- u16_t cwnd;
- u16_t ssthresh;
-
- /* sender variables */
- u32_t snd_nxt, /* next seqno to be sent */
- snd_max; /* Highest seqno sent. */
- u16_t snd_wnd; /* sender window */
- u32_t snd_wl1, snd_wl2, /* Sequence and acknowledgement numbers of last
- window update. */
- snd_lbb; /* Sequence number of next byte to be buffered. */
-
- u16_t acked;
-
- u16_t snd_buf; /* Available buffer space for sending (in bytes). */
-#define TCP_SNDQUEUELEN_OVERFLOW (0xffff-3)
- u16_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */
-
-
- /* These are ordered by sequence number: */
- struct tcp_seg *unsent; /* Unsent (queued) segments. */
- struct tcp_seg *unacked; /* Sent but unacknowledged segments. */
-#if TCP_QUEUE_OOSEQ
- struct tcp_seg *ooseq; /* Received out of sequence segments. */
-#endif /* TCP_QUEUE_OOSEQ */
-
- struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */
-
-#if LWIP_CALLBACK_API
- /* Function to be called when more send buffer space is available.
- * @param arg user-supplied argument (tcp_pcb.callback_arg)
- * @param pcb the tcp_pcb which has send buffer space available
- * @param space the amount of bytes available
- * @return ERR_OK: try to send some data by calling tcp_output
- */
- err_t (* sent)(void *arg, struct tcp_pcb *pcb, u16_t space);
-
- /* Function to be called when (in-sequence) data has arrived.
- * @param arg user-supplied argument (tcp_pcb.callback_arg)
- * @param pcb the tcp_pcb for which data has arrived
- * @param p the packet buffer which arrived
- * @param err an error argument (TODO: that is current always ERR_OK?)
- * @return ERR_OK: try to send some data by calling tcp_output
- */
- err_t (* recv)(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
-
- /* Function to be called when a connection has been set up.
- * @param arg user-supplied argument (tcp_pcb.callback_arg)
- * @param pcb the tcp_pcb that now is connected
- * @param err an error argument (TODO: that is current always ERR_OK?)
- * @return value is currently ignored
- */
- err_t (* connected)(void *arg, struct tcp_pcb *pcb, err_t err);
-
- /* Function to call when a listener has been connected.
- * @param arg user-supplied argument (tcp_pcb.callback_arg)
- * @param pcb a new tcp_pcb that now is connected
- * @param err an error argument (TODO: that is current always ERR_OK?)
- * @return ERR_OK: accept the new connection,
- * any other err_t abortsthe new connection
- */
- err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);
-
- /* Function which is called periodically.
- * The period can be adjusted in multiples of the TCP slow timer interval
- * by changing tcp_pcb.polltmr.
- * @param arg user-supplied argument (tcp_pcb.callback_arg)
- * @param pcb the tcp_pcb to poll for
- * @return ERR_OK: try to send some data by calling tcp_output
- */
- err_t (* poll)(void *arg, struct tcp_pcb *pcb);
-
- /* Function to be called whenever a fatal error occurs.
- * There is no pcb parameter since most of the times, the pcb is
- * already deallocated (or there is no pcb) when this function is called.
- * @param arg user-supplied argument (tcp_pcb.callback_arg)
- * @param err an indication why the error callback is called:
- * ERR_ABRT: aborted through tcp_abort or by a TCP timer
- * ERR_RST: the connection was reset by the remote host
- */
- void (* errf)(void *arg, err_t err);
-#endif /* LWIP_CALLBACK_API */
-
- /* idle time before KEEPALIVE is sent */
- u32_t keep_idle;
-#if LWIP_TCP_KEEPALIVE
- u32_t keep_intvl;
- u32_t keep_cnt;
-#endif /* LWIP_TCP_KEEPALIVE */
-
- /* Persist timer counter */
- u32_t persist_cnt;
- /* Persist timer back-off */
- u8_t persist_backoff;
-
- /* KEEPALIVE counter */
- u8_t keep_cnt_sent;
-};
-
-struct tcp_pcb_listen {
-/* Common members of all PCB types */
- IP_PCB;
-/* Protocol specific PCB members */
- TCP_PCB_COMMON(struct tcp_pcb_listen);
-
-#if LWIP_CALLBACK_API
- /* Function to call when a listener has been connected.
- * @param arg user-supplied argument (tcp_pcb.callback_arg)
- * @param pcb a new tcp_pcb that now is connected
- * @param err an error argument (TODO: that is current always ERR_OK?)
- * @return ERR_OK: accept the new connection,
- * any other err_t abortsthe new connection
- */
- err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);
-#endif /* LWIP_CALLBACK_API */
-#if TCP_LISTEN_BACKLOG
- u8_t backlog;
- u8_t accepts_pending;
-#endif /* TCP_LISTEN_BACKLOG */
-};
-
-#if LWIP_EVENT_API
-
-enum lwip_event {
- LWIP_EVENT_ACCEPT,
- LWIP_EVENT_SENT,
- LWIP_EVENT_RECV,
- LWIP_EVENT_CONNECTED,
- LWIP_EVENT_POLL,
- LWIP_EVENT_ERR
-};
-
-err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
- enum lwip_event,
- struct pbuf *p,
- u16_t size,
- err_t err);
-
-#define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
- LWIP_EVENT_ACCEPT, NULL, 0, err)
-#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
- LWIP_EVENT_SENT, NULL, space, ERR_OK)
-#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
- LWIP_EVENT_RECV, (p), 0, (err))
-#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
- LWIP_EVENT_CONNECTED, NULL, 0, (err))
-#define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
- LWIP_EVENT_POLL, NULL, 0, ERR_OK)
-#define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \
- LWIP_EVENT_ERR, NULL, 0, (err))
-#else /* LWIP_EVENT_API */
-#define TCP_EVENT_ACCEPT(pcb,err,ret) \
- if((pcb)->accept != NULL) \
- (ret = (pcb)->accept((pcb)->callback_arg,(pcb),(err)))
-#define TCP_EVENT_SENT(pcb,space,ret) \
- if((pcb)->sent != NULL) \
- (ret = (pcb)->sent((pcb)->callback_arg,(pcb),(space)))
-#define TCP_EVENT_RECV(pcb,p,err,ret) \
- if((pcb)->recv != NULL) \
- { ret = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); } else { \
- ret = ERR_OK; \
- if (p) pbuf_free(p); }
-#define TCP_EVENT_CONNECTED(pcb,err,ret) \
- if((pcb)->connected != NULL) \
- (ret = (pcb)->connected((pcb)->callback_arg,(pcb),(err)))
-#define TCP_EVENT_POLL(pcb,ret) \
- if((pcb)->poll != NULL) \
- (ret = (pcb)->poll((pcb)->callback_arg,(pcb)))
-#define TCP_EVENT_ERR(errf,arg,err) \
- if((errf) != NULL) \
- (errf)((arg),(err))
-#endif /* LWIP_EVENT_API */
-
-/* This structure represents a TCP segment on the unsent and unacked queues */
-struct tcp_seg {
- struct tcp_seg *next; /* used when putting segements on a queue */
- struct pbuf *p; /* buffer containing data + TCP header */
- void *dataptr; /* pointer to the TCP data in the pbuf */
- u16_t len; /* the TCP length of this segment */
- struct tcp_hdr *tcphdr; /* the TCP header */
-};
-
-/* Internal functions and global variables: */
-struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);
-void tcp_pcb_purge(struct tcp_pcb *pcb);
-void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);
-
-u8_t tcp_segs_free(struct tcp_seg *seg);
-u8_t tcp_seg_free(struct tcp_seg *seg);
-struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);
-
-#define tcp_ack(pcb) if((pcb)->flags & TF_ACK_DELAY) { \
- (pcb)->flags &= ~TF_ACK_DELAY; \
- (pcb)->flags |= TF_ACK_NOW; \
- tcp_output(pcb); \
- } else { \
- (pcb)->flags |= TF_ACK_DELAY; \
- }
-
-#define tcp_ack_now(pcb) (pcb)->flags |= TF_ACK_NOW; \
- tcp_output(pcb)
-
-err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags);
-err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len,
- u8_t flags, u8_t apiflags,
- u8_t *optdata, u8_t optlen);
-
-void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);
-
-void tcp_rst(u32_t seqno, u32_t ackno,
- struct ip_addr *local_ip, struct ip_addr *remote_ip,
- u16_t local_port, u16_t remote_port);
-
-u32_t tcp_next_iss(void);
-
-void tcp_keepalive(struct tcp_pcb *pcb);
-void tcp_zero_window_probe(struct tcp_pcb *pcb);
-
-#if TCP_CALCULATE_EFF_SEND_MSS
-u16_t tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr);
-#endif /* TCP_CALCULATE_EFF_SEND_MSS */
-
-extern struct tcp_pcb *tcp_input_pcb;
-extern u32_t tcp_ticks;
-
-#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
-void tcp_debug_print(struct tcp_hdr *tcphdr);
-void tcp_debug_print_flags(u8_t flags);
-void tcp_debug_print_state(enum tcp_state s);
-void tcp_debug_print_pcbs(void);
-s16_t tcp_pcbs_sane(void);
-#else
-# define tcp_debug_print(tcphdr)
-# define tcp_debug_print_flags(flags)
-# define tcp_debug_print_state(s)
-# define tcp_debug_print_pcbs()
-# define tcp_pcbs_sane() 1
-#endif /* TCP_DEBUG */
-
-#if NO_SYS
-#define tcp_timer_needed()
-#else
-void tcp_timer_needed(void);
-#endif
-
-/* The TCP PCB lists. */
-union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */
- struct tcp_pcb_listen *listen_pcbs;
- struct tcp_pcb *pcbs;
-};
-extern union tcp_listen_pcbs_t tcp_listen_pcbs;
-extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a
- state in which they accept or send
- data. */
-extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */
-
-extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */
-
-/* Axioms about the above lists:
- 1) Every TCP PCB that is not CLOSED is in one of the lists.
- 2) A PCB is only in one of the lists.
- 3) All PCBs in the tcp_listen_pcbs list is in LISTEN state.
- 4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state.
-*/
-
-/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB
- with a PCB list or removes a PCB from a list, respectively. */
-#if 0
-#define TCP_REG(pcbs, npcb) do {\
- LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", npcb, npcb->local_port)); \
- for(tcp_tmp_pcb = *pcbs; \
- tcp_tmp_pcb != NULL; \
- tcp_tmp_pcb = tcp_tmp_pcb->next) { \
- LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != npcb); \
- } \
- LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); \
- npcb->next = *pcbs; \
- LWIP_ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); \
- *(pcbs) = npcb; \
- LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
- tcp_timer_needed(); \
- } while(0)
-#define TCP_RMV(pcbs, npcb) do { \
- LWIP_ASSERT("TCP_RMV: pcbs != NULL", *pcbs != NULL); \
- LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", npcb, *pcbs)); \
- if(*pcbs == npcb) { \
- *pcbs = (*pcbs)->next; \
- } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
- if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
- tcp_tmp_pcb->next = npcb->next; \
- break; \
- } \
- } \
- npcb->next = NULL; \
- LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
- LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", npcb, *pcbs)); \
- } while(0)
-
-#else /* LWIP_DEBUG */
-#define TCP_REG(pcbs, npcb) do { \
- npcb->next = *pcbs; \
- *(pcbs) = npcb; \
- tcp_timer_needed(); \
- } while(0)
-#define TCP_RMV(pcbs, npcb) do { \
- if(*(pcbs) == npcb) { \
- (*(pcbs)) = (*pcbs)->next; \
- } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
- if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
- tcp_tmp_pcb->next = npcb->next; \
- break; \
- } \
- } \
- npcb->next = NULL; \
- } while(0)
-#endif /* LWIP_DEBUG */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_TCP */
-
-#endif /* __LWIP_TCP_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_TCPIP_H__
-#define __LWIP_TCPIP_H__
-
-#include "lwip/opt.h"
-
-#if !NO_SYS /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/api_msg.h"
-#include "lwip/netifapi.h"
-#include "lwip/pbuf.h"
-#include "lwip/api.h"
-#include "lwip/sys.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if LWIP_TCPIP_CORE_LOCKING
-/** The global semaphore to lock the stack. */
-extern sys_sem_t lock_tcpip_core;
-#define LOCK_TCPIP_CORE() sys_sem_wait(lock_tcpip_core)
-#define UNLOCK_TCPIP_CORE() sys_sem_signal(lock_tcpip_core)
-#define TCPIP_APIMSG(m) tcpip_apimsg_lock(m)
-#define TCPIP_APIMSG_ACK(m)
-#define TCPIP_NETIFAPI(m) tcpip_netifapi_lock(m)
-#define TCPIP_NETIFAPI_ACK(m)
-#else
-#define LOCK_TCPIP_CORE()
-#define UNLOCK_TCPIP_CORE()
-#define TCPIP_APIMSG(m) tcpip_apimsg(m)
-#define TCPIP_APIMSG_ACK(m) sys_sem_signal(m->conn->op_completed)
-#define TCPIP_NETIFAPI(m) tcpip_netifapi(m)
-#define TCPIP_NETIFAPI_ACK(m) sys_sem_signal(m->sem)
-#endif /* LWIP_TCPIP_CORE_LOCKING */
-
-void tcpip_init(void (* tcpip_init_done)(void *), void *arg);
-
-#if LWIP_NETCONN
-err_t tcpip_apimsg(struct api_msg *apimsg);
-#if LWIP_TCPIP_CORE_LOCKING
-err_t tcpip_apimsg_lock(struct api_msg *apimsg);
-#endif /* LWIP_TCPIP_CORE_LOCKING */
-#endif /* LWIP_NETCONN */
-
-err_t tcpip_input(struct pbuf *p, struct netif *inp);
-
-#if LWIP_NETIF_API
-err_t tcpip_netifapi(struct netifapi_msg *netifapimsg);
-#if LWIP_TCPIP_CORE_LOCKING
-err_t tcpip_netifapi_lock(struct netifapi_msg *netifapimsg);
-#endif /* LWIP_TCPIP_CORE_LOCKING */
-#endif /* LWIP_NETIF_API */
-
-err_t tcpip_callback_with_block(void (*f)(void *ctx), void *ctx, u8_t block);
-#define tcpip_callback(f,ctx) tcpip_callback_with_block(f,ctx,1)
-
-err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg);
-#define tcpip_untimeout(h, arg) tcpip_timeout(0xffffffff, h, arg)
-
-enum tcpip_msg_type {
-#if LWIP_NETCONN
- TCPIP_MSG_API,
-#endif /* LWIP_NETCONN */
- TCPIP_MSG_INPKT,
-#if LWIP_NETIF_API
- TCPIP_MSG_NETIFAPI,
-#endif /* LWIP_NETIF_API */
- TCPIP_MSG_CALLBACK,
- TCPIP_MSG_TIMEOUT
-};
-
-struct tcpip_msg {
- enum tcpip_msg_type type;
- sys_sem_t *sem;
- union {
-#if LWIP_NETCONN
- struct api_msg *apimsg;
-#endif /* LWIP_NETCONN */
-#if LWIP_NETIF_API
- struct netifapi_msg *netifapimsg;
-#endif /* LWIP_NETIF_API */
- struct {
- struct pbuf *p;
- struct netif *netif;
- } inp;
- struct {
- void (*f)(void *ctx);
- void *ctx;
- } cb;
- struct {
- u32_t msecs;
- sys_timeout_handler h;
- void *arg;
- } tmo;
- } msg;
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !NO_SYS */
-
-#endif /* __LWIP_TCPIP_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_UDP_H__
-#define __LWIP_UDP_H__
-
-#include "lwip/opt.h"
-
-#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/pbuf.h"
-#include "lwip/netif.h"
-#include "lwip/ip_addr.h"
-#include "lwip/ip.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define UDP_HLEN 8
-
-/* Fields are (of course) in network byte order. */
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct udp_hdr {
- PACK_STRUCT_FIELD(u16_t src);
- PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */
- PACK_STRUCT_FIELD(u16_t len);
- PACK_STRUCT_FIELD(u16_t chksum);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-#define UDP_FLAGS_NOCHKSUM 0x01U
-#define UDP_FLAGS_UDPLITE 0x02U
-#define UDP_FLAGS_CONNECTED 0x04U
-
-struct udp_pcb {
-/* Common members of all PCB types */
- IP_PCB;
-
-/* Protocol specific PCB members */
-
- struct udp_pcb *next;
-
- u8_t flags;
- /* ports are in host byte order */
- u16_t local_port, remote_port;
-
-#if LWIP_IGMP
- /* outgoing network interface for multicast packets */
- struct ip_addr multicast_ip;
-#endif /* LWIP_IGMP */
-
-#if LWIP_UDPLITE
- /* used for UDP_LITE only */
- u16_t chksum_len_rx, chksum_len_tx;
-#endif /* LWIP_UDPLITE */
-
- /* receive callback function
- * addr and port are in same byte order as in the pcb
- * The callback is responsible for freeing the pbuf
- * if it's not used any more.
- *
- * @param arg user supplied argument (udp_pcb.recv_arg)
- * @param pcb the udp_pcb which received data
- * @param p the packet buffer that was received
- * @param addr the remote IP address from which the packet was received
- * @param port the remote port from which the packet was received
- */
- void (* recv)(void *arg, struct udp_pcb *pcb, struct pbuf *p,
- struct ip_addr *addr, u16_t port);
- /* user-supplied argument for the recv callback */
- void *recv_arg;
-};
-/* udp_pcbs export for exernal reference (e.g. SNMP agent) */
-extern struct udp_pcb *udp_pcbs;
-
-/* The following functions is the application layer interface to the
- UDP code. */
-struct udp_pcb * udp_new (void);
-void udp_remove (struct udp_pcb *pcb);
-err_t udp_bind (struct udp_pcb *pcb, struct ip_addr *ipaddr,
- u16_t port);
-err_t udp_connect (struct udp_pcb *pcb, struct ip_addr *ipaddr,
- u16_t port);
-void udp_disconnect (struct udp_pcb *pcb);
-void udp_recv (struct udp_pcb *pcb,
- void (* recv)(void *arg, struct udp_pcb *upcb,
- struct pbuf *p,
- struct ip_addr *addr,
- u16_t port),
- void *recv_arg);
-err_t udp_sendto_if (struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *dst_ip, u16_t dst_port, struct netif *netif);
-err_t udp_sendto (struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *dst_ip, u16_t dst_port);
-err_t udp_send (struct udp_pcb *pcb, struct pbuf *p);
-
-#define udp_flags(pcb) ((pcb)->flags)
-#define udp_setflags(pcb, f) ((pcb)->flags = (f))
-
-/* The following functions are the lower layer interface to UDP. */
-void udp_input (struct pbuf *p, struct netif *inp);
-
-#define udp_init() /* Compatibility define, not init needed. */
-
-#if UDP_DEBUG
-void udp_debug_print(struct udp_hdr *udphdr);
-#else
-#define udp_debug_print(udphdr)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_UDP */
-
-#endif /* __LWIP_UDP_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
- * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
- * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-#ifndef __NETIF_ETHARP_H__
-#define __NETIF_ETHARP_H__
-
-#include "lwip/opt.h"
-
-#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/ip.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef ETH_PAD_SIZE
-#define ETH_PAD_SIZE 0
-#endif
-
-#ifndef ETHARP_HWADDR_LEN
-#define ETHARP_HWADDR_LEN 6
-#endif
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct eth_addr {
- PACK_STRUCT_FIELD(u8_t addr[ETHARP_HWADDR_LEN]);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct eth_hdr {
-#if ETH_PAD_SIZE
- PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]);
-#endif
- PACK_STRUCT_FIELD(struct eth_addr dest);
- PACK_STRUCT_FIELD(struct eth_addr src);
- PACK_STRUCT_FIELD(u16_t type);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-/** the ARP message */
-struct etharp_hdr {
- PACK_STRUCT_FIELD(struct eth_hdr ethhdr);
- PACK_STRUCT_FIELD(u16_t hwtype);
- PACK_STRUCT_FIELD(u16_t proto);
- PACK_STRUCT_FIELD(u16_t _hwlen_protolen);
- PACK_STRUCT_FIELD(u16_t opcode);
- PACK_STRUCT_FIELD(struct eth_addr shwaddr);
- PACK_STRUCT_FIELD(struct ip_addr2 sipaddr);
- PACK_STRUCT_FIELD(struct eth_addr dhwaddr);
- PACK_STRUCT_FIELD(struct ip_addr2 dipaddr);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct ethip_hdr {
- PACK_STRUCT_FIELD(struct eth_hdr eth);
- PACK_STRUCT_FIELD(struct ip_hdr ip);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-/** 5 seconds period */
-#define ARP_TMR_INTERVAL 5000
-
-#define ETHTYPE_ARP 0x0806
-#define ETHTYPE_IP 0x0800
-#define ETHTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */
-#define ETHTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */
-
-/** ARP message types (opcodes) */
-#define ARP_REQUEST 1
-#define ARP_REPLY 2
-
-#if ARP_QUEUEING
-/** struct for queueing outgoing packets for unknown address
- * defined here to be accessed by memp.h
- */
-struct etharp_q_entry {
- struct etharp_q_entry *next;
- struct pbuf *p;
-};
-#endif /* ARP_QUEUEING */
-
-#define etharp_init() /* Compatibility define, not init needed. */
-void etharp_tmr(void);
-s8_t etharp_find_addr(struct netif *netif, struct ip_addr *ipaddr,
- struct eth_addr **eth_ret, struct ip_addr **ip_ret);
-void etharp_ip_input(struct netif *netif, struct pbuf *p);
-void etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr,
- struct pbuf *p);
-err_t etharp_output(struct netif *netif, struct pbuf *q, struct ip_addr *ipaddr);
-err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q);
-err_t etharp_request(struct netif *netif, struct ip_addr *ipaddr);
-
-err_t ethernet_input(struct pbuf *p, struct netif *netif);
-
-#if LWIP_AUTOIP
-err_t etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
- const struct eth_addr *ethdst_addr,
- const struct eth_addr *hwsrc_addr, const struct ip_addr *ipsrc_addr,
- const struct eth_addr *hwdst_addr, const struct ip_addr *ipdst_addr,
- const u16_t opcode);
-#endif /* LWIP_AUTOIP */
-
-#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETHARP_HWADDR_LEN) == 0)
-
-extern const struct eth_addr ethbroadcast, ethzero;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_ARP */
-
-#endif /* __NETIF_ARP_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __NETIF_LOOPIF_H__
-#define __NETIF_LOOPIF_H__
-
-#include "lwip/netif.h"
-#include "lwip/err.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if !LWIP_LOOPIF_MULTITHREADING
-void loopif_poll(struct netif *netif);
-#endif
-
-err_t loopif_init(struct netif *netif);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __NETIF_LOOPIF_H__ */
+++ /dev/null
-/*****************************************************************************
-* ppp_oe.h - PPP Over Ethernet implementation for lwIP.
-*
-* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc.
-*
-* The authors hereby grant permission to use, copy, modify, distribute,
-* and license this software and its documentation for any purpose, provided
-* that existing copyright notices are retained in all copies and that this
-* notice and the following disclaimer are included verbatim in any
-* distributions. No written agreement, license, or royalty fee is required
-* for any of the authorized uses.
-*
-* THIS SOFTWARE IS PROVIDED BY THE 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 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.
-*
-******************************************************************************
-* REVISION HISTORY
-*
-* 06-01-01 Marc Boucher <marc@mbsi.ca>
-* Ported to lwIP.
-*****************************************************************************/
-
-
-
-/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */
-
-/*-
- * Copyright (c) 2002 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Martin Husemann <martin@NetBSD.org>.
- *
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
- */
-#ifndef PPP_OE_H
-#define PPP_OE_H
-
-#include "lwip/opt.h"
-
-#if PPPOE_SUPPORT > 0
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct pppoehdr {
- PACK_STRUCT_FIELD(u8_t vertype);
- PACK_STRUCT_FIELD(u8_t code);
- PACK_STRUCT_FIELD(u16_t session);
- PACK_STRUCT_FIELD(u16_t plen);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct pppoetag {
- PACK_STRUCT_FIELD(u16_t tag);
- PACK_STRUCT_FIELD(u16_t len);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-
-#define PPPOE_STATE_INITIAL 0
-#define PPPOE_STATE_PADI_SENT 1
-#define PPPOE_STATE_PADR_SENT 2
-#define PPPOE_STATE_SESSION 3
-#define PPPOE_STATE_CLOSING 4
-/* passive */
-#define PPPOE_STATE_PADO_SENT 1
-
-#define PPPOE_HEADERLEN sizeof(struct pppoehdr)
-#define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */
-
-#define PPPOE_TAG_EOL 0x0000 /* end of list */
-#define PPPOE_TAG_SNAME 0x0101 /* service name */
-#define PPPOE_TAG_ACNAME 0x0102 /* access concentrator name */
-#define PPPOE_TAG_HUNIQUE 0x0103 /* host unique */
-#define PPPOE_TAG_ACCOOKIE 0x0104 /* AC cookie */
-#define PPPOE_TAG_VENDOR 0x0105 /* vendor specific */
-#define PPPOE_TAG_RELAYSID 0x0110 /* relay session id */
-#define PPPOE_TAG_SNAME_ERR 0x0201 /* service name error */
-#define PPPOE_TAG_ACSYS_ERR 0x0202 /* AC system error */
-#define PPPOE_TAG_GENERIC_ERR 0x0203 /* gerneric error */
-
-#define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */
-#define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */
-#define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */
-#define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */
-#define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */
-
-#ifndef ETHERMTU
-#define ETHERMTU 1500
-#endif
-
-/* two byte PPP protocol discriminator, then IP data */
-#define PPPOE_MAXMTU (ETHERMTU-PPPOE_HEADERLEN-2)
-
-struct pppoe_softc;
-
-
-void pppoe_init(void);
-
-err_t pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr);
-err_t pppoe_destroy(struct netif *ifp);
-
-int pppoe_connect(struct pppoe_softc *sc);
-void pppoe_disconnect(struct pppoe_softc *sc);
-
-void pppoe_disc_input(struct netif *netif, struct pbuf *p);
-void pppoe_data_input(struct netif *netif, struct pbuf *p);
-
-err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb);
-
-extern int pppoe_hdrlen;
-
-#endif /* PPPOE_SUPPORT */
-
-#endif /* PPP_OE_H */
+++ /dev/null
-/*
- * Copyright (c) 2001, Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * 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. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
- *
- * This file is part of the lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __NETIF_SLIPIF_H__
-#define __NETIF_SLIPIF_H__
-
-#include "lwip/netif.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-err_t slipif_init(struct netif * netif);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
#include <palacios/vm_guest_mem.h>
#include <palacios/vmm_decoder.h>
+#include <palacios/vmm_string.h>
PrintDebug("Host Address of rip = 0x%x\n", host_addr);
PrintDebug("Instr (15 bytes) at %x:\n", host_addr);
- PrintTraceMemDump((char*)host_addr, 15);
+ PrintTraceMemDump((uchar_t *)host_addr, 15);
break;
}
// Setup the host state save area
host_state = V3_AllocPages(4);
- msr.e_reg.high = 0;
- msr.e_reg.low = (uint_t)host_state;
+ /* 64-BIT-ISSUE */
+ // msr.e_reg.high = 0;
+ //msr.e_reg.low = (uint_t)host_state;
+ msr.r_reg = (addr_t)host_state;
- PrintDebug("Host State being saved at %x\n", (uint_t)host_state);
+ PrintDebug("Host State being saved at %x\n", (addr_t)host_state);
Set_MSR(SVM_VM_HSAVE_PA_MSR, msr.e_reg.high, msr.e_reg.low);
#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);
// PrintDebug("SVM Returned: Exit Code: 0x%x \t\t(tsc=%ul)\n",exit_code, (uint_t)info->time_state.guest_tsc);
if ((0) && (exit_code < 0x4f)) {
- char instr[32];
+ uchar_t instr[32];
int ret;
// Dump out the instr stream
default: {
addr_t rip_addr;
- char buf[15];
+ uchar_t buf[15];
addr_t host_addr;
PrintDebug("Unhandled SVM Exit: %s\n", vmexit_code_to_str(exit_code));
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:
/* This is a straight address conversion + copy,
* except for the tiny little issue of crossing page boundries.....
*/
-int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, char * dest) {
+int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, uchar_t * dest) {
addr_t cursor = guest_va;
int bytes_read = 0;
/* This is a straight address conversion + copy,
* except for the tiny little issue of crossing page boundries.....
*/
-int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * dest) {
+int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * dest) {
addr_t cursor = guest_pa;
int bytes_read = 0;
/* This is a straight address conversion + copy,
* except for the tiny little issue of crossing page boundries.....
*/
-int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * src) {
+int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * src) {
addr_t cursor = guest_pa;
int bytes_written = 0;
#include <devices/8254.h>
#include <devices/nvram.h>
#include <devices/generic.h>
+#include <devices/ramdisk.h>
+#include <devices/cdrom.h>
+
+
+#define USE_GENERIC 1
+
+#define MAGIC_CODE 0xf1e2d3c4
+
+
+
+struct layout_region {
+ ulong_t length;
+ ulong_t final_addr;
+};
+
+struct guest_mem_layout {
+ ulong_t magic;
+ ulong_t num_regions;
+ struct layout_region regions[0];
+};
+
}
*/
-int config_guest(struct guest_info * info, void * config_ptr) {
+int config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) {
- struct guest_mem_layout * layout = (struct guest_mem_layout *)config_ptr;
+ struct guest_mem_layout * layout = (struct guest_mem_layout *)config_ptr->vm_kernel;
extern v3_cpu_arch_t v3_cpu_type;
void * region_start;
int i;
-
+ int use_ramdisk = config_ptr->use_ramdisk;
+ int use_generic = USE_GENERIC;
+
+
v3_init_time(info);
init_shadow_map(info);
{
-
+ struct vm_device * ramdisk = NULL;
+ struct vm_device * cdrom = 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;
+
+
+
+
+ if (use_ramdisk) {
+ PrintDebug("Creating Ramdisk\n");
+ ramdisk = create_ramdisk();
+ cdrom = v3_create_cdrom(ramdisk, config_ptr->ramdisk, config_ptr->ramdisk_size);
+ }
-#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);
+ v3_attach_device(info, cdrom);
+ }
-#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);
+ v3_hook_passthrough_irq(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_passthrough_irq(info, 14);
+ // secondary ide
+ v3_hook_passthrough_irq(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
// First Attempt = 494 lines
// current = 106 lines
int handle_cr0_write(struct guest_info * info) {
- char instr[15];
+ uchar_t instr[15];
int ret;
struct x86_instr dec_instr;
// First attempt = 253 lines
// current = 51 lines
int handle_cr0_read(struct guest_info * info) {
- char instr[15];
+ uchar_t instr[15];
int ret;
struct x86_instr dec_instr;
// current = 65 lines
int handle_cr3_write(struct guest_info * info) {
int ret;
- char instr[15];
+ uchar_t instr[15];
struct x86_instr dec_instr;
if (info->mem_mode == PHYSICAL_MEM) {
// first attempt = 156 lines
// current = 36 lines
int handle_cr3_read(struct guest_info * info) {
- char instr[15];
+ uchar_t instr[15];
int ret;
struct x86_instr dec_instr;
#include <palacios/vmm.h>
-void PrintDebugHex(unsigned char x)
+void PrintDebugHex(uchar_t x)
{
unsigned char z;
- z = (x>>4) & 0xf ;
+ z = (x >> 4) & 0xf ;
PrintDebug("%x", z);
z = x & 0xf;
PrintDebug("%x", z);
}
-void PrintDebugMemDump(unsigned char *start, int n)
+void PrintDebugMemDump(uchar_t *start, int n)
{
int i, j;
- for (i=0;i<n;i+=16) {
- PrintDebug("%8x", (unsigned)(start+i));
- for (j=i; j<i+16 && j<n; j+=2) {
+ for (i = 0; i < n; i += 16) {
+ PrintDebug("%8x", (start + i));
+
+ for (j = i; (j < (i + 16)) && (j < n); j += 2) {
PrintDebug(" ");
- PrintDebugHex(*((unsigned char *)(start+j)));
- if ((j+1)<n) {
- PrintDebugHex(*((unsigned char *)(start+j+1)));
+ PrintDebugHex(*((uchar_t *)(start + j)));
+
+ if ((j + 1) < n) {
+ PrintDebugHex(*((uchar_t *)(start + j + 1)));
}
+
}
+
PrintDebug(" ");
- for (j=i; j<i+16 && j<n;j++) {
- PrintDebug("%c", ((start[j]>=32) && (start[j]<=126)) ? start[j] : '.');
+
+ for (j = i; (j < (i + 16)) && (j < n); j++) {
+ PrintDebug("%c", ((start[j] >= 32) && (start[j] <= 126)) ? start[j] : '.');
}
+
PrintDebug("\n");
}
}
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);
}
int (*read)(addr_t read_addr, void * dst, uint_t length, void * priv_data),
addr_t read_gpa, void * private_data) {
struct basic_instr_info instr_info;
- char instr[15];
+ uchar_t instr[15];
int ret;
struct emulated_page * data_page = V3_Malloc(sizeof(struct emulated_page));
addr_t data_addr_offset = PT32_PAGE_OFFSET(read_gva);
addr_t write_gpa, void * private_data) {
struct basic_instr_info instr_info;
- char instr[15];
+ uchar_t instr[15];
int ret;
struct write_region * write_op = V3_Malloc(sizeof(struct write_region ));
struct emulated_page * data_page = V3_Malloc(sizeof(struct emulated_page));
htable->entry_count = 0;
htable->hash_fn = hash_fn;
htable->eq_fn = eq_fn;
- htable->load_limit = (uint_t) ceil((double)(size * max_load_factor));
+ htable->load_limit = (uint_t) v3_ceil((double)(size * max_load_factor));
return htable;
}
htable->table_length = new_size;
- htable->load_limit = (uint_t) ceil(new_size * max_load_factor);
+ htable->load_limit = (uint_t) v3_ceil(new_size * max_load_factor);
return -1;
}
-/*Zheng 07/30/2008*/
+
void init_interrupt_state(struct guest_info * info) {
info->intr_state.excp_pending = 0;
info->intr_state.excp_num = 0;
info->intr_state.excp_error_code = 0;
+ memset((uchar_t *)(info->intr_state.hooks), 0, sizeof(struct v3_irq_hook *) * 256);
+
info->vm_ops.raise_irq = &v3_raise_irq;
- info->vm_ops.lower_irq = &v3_lower_irq; //Zheng added
+ info->vm_ops.lower_irq = &v3_lower_irq;
}
void set_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * state) {
-// This structure is used to dispatch
-// interrupts delivered to vmm via deliver interrupt to vmm
-// it is what we put into the opaque field given to
-// the host os when we install the handler
-struct vmm_intr_decode {
- void (*handler)(struct vmm_intr_state *state);
- // This opaque is user supplied by the caller
- // of hook_irq_new
- void *opaque;
-};
-int v3_hook_irq(uint_t irq,
- void (*handler)(struct vmm_intr_state *state),
- void *opaque)
+static inline struct v3_irq_hook * get_irq_hook(struct guest_info * info, uint_t irq) {
+ V3_ASSERT(irq <= 256);
+ return info->intr_state.hooks[irq];
+}
+
+
+int v3_hook_irq(struct guest_info * info,
+ uint_t irq,
+ int (*handler)(struct guest_info * info, struct v3_interrupt * intr, void * priv_data),
+ void * priv_data)
{
- struct vmm_intr_decode *d = (struct vmm_intr_decode *)V3_Malloc(sizeof(struct vmm_intr_decode));
+ struct v3_irq_hook * hook = (struct v3_irq_hook *)V3_Malloc(sizeof(struct v3_irq_hook));
- if (!d) { return -1; }
+ if (hook == NULL) {
+ return -1;
+ }
- d->handler = handler;
- d->opaque = opaque;
+ if (get_irq_hook(info, irq) != NULL) {
+ PrintError("IRQ %d already hooked\n", irq);
+ return -1;
+ }
+
+ hook->handler = handler;
+ hook->priv_data = priv_data;
- if (V3_Hook_Interrupt(irq,d)) {
- PrintError("hook_irq: failed to hook irq 0x%x to decode 0x%x\n", irq,d);
+ info->intr_state.hooks[irq] = hook;
+
+ if (V3_Hook_Interrupt(info, irq)) {
+ PrintError("hook_irq: failed to hook irq %d\n", irq);
return -1;
} else {
- PrintDebug("hook_irq: hooked irq 0x%x to decode 0x%x\n", irq,d);
+ PrintDebug("hook_irq: hooked irq %d\n", irq);
return 0;
}
}
-void deliver_interrupt_to_vmm(struct vmm_intr_state *state)
-{
-
- PrintDebug("deliver_interrupt_to_vmm: state=0x%x\n",state);
-
- struct vmm_intr_decode *d = (struct vmm_intr_decode *)(state->opaque);
-
- void *temp = state->opaque;
- state->opaque = d->opaque;
- d->handler(state);
-
- state->opaque=temp;
-}
+static int passthrough_irq_handler(struct guest_info * info, struct v3_interrupt * intr, void * priv_data)
+{
+ PrintDebug("[passthrough_irq_handler] raise_irq=%d (guest=0x%x)\n", intr->irq, info);
+ return v3_raise_irq(info, intr->irq);
-static void guest_injection_irq_handler(struct vmm_intr_state *state)
-{
- struct guest_info *guest = (struct guest_info *)(state->opaque);
- PrintDebug("[guest_injection_irq_handler] raise_irq=0x%x (guest=0x%x)\n", state->irq, guest);
- PrintDebug("guest_irq_injection: state=0x%x\n", state);
- guest->vm_ops.raise_irq(guest,state->irq);
}
-
-int v3_hook_irq_for_guest_injection(struct guest_info *info, int irq)
+int v3_hook_passthrough_irq(struct guest_info * info, uint_t irq)
{
- int rc = v3_hook_irq(irq,
- guest_injection_irq_handler,
- info);
+ int rc = v3_hook_irq(info,
+ irq,
+ passthrough_irq_handler,
+ NULL);
if (rc) {
PrintError("guest_irq_injection: failed to hook irq 0x%x (guest=0x%x)\n", irq, info);
+
+int v3_deliver_irq(struct guest_info * info, struct v3_interrupt * intr) {
+ PrintDebug("v3_deliver_irq: irq=%d state=0x%x, \n", intr->irq, intr);
+
+ struct v3_irq_hook * hook = get_irq_hook(info, intr->irq);
+
+ if (hook == NULL) {
+ PrintError("Attempting to deliver interrupt to non registered hook(irq=%d)\n", intr->irq);
+ return -1;
+ }
+
+ return hook->handler(info, intr, hook->priv_data);
+}
+
+
+
+
+
+
+
+
int v3_raise_exception_with_error(struct guest_info * info, uint_t excp, uint_t error_code) {
- struct vm_intr * intr_state = &(info->intr_state);
+ struct v3_intr_state * intr_state = &(info->intr_state);
if (intr_state->excp_pending == 0) {
intr_state->excp_pending = 1;
}
int v3_raise_exception(struct guest_info * info, uint_t excp) {
- struct vm_intr * intr_state = &(info->intr_state);
+ struct v3_intr_state * intr_state = &(info->intr_state);
PrintDebug("[v3_raise_exception]\n");
if (intr_state->excp_pending == 0) {
intr_state->excp_pending = 1;
return 0;
}
-/*Zheng 07/30/2008*/
int v3_lower_irq(struct guest_info * info, int irq) {
// Look up PIC and resend
V3_ASSERT(info);
V3_ASSERT(info->intr_state.controller);
- V3_ASSERT(info->intr_state.controller->raise_intr);
+ V3_ASSERT(info->intr_state.controller->lower_intr);
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->lower_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;
}
int intr_pending(struct guest_info * info) {
- struct vm_intr * intr_state = &(info->intr_state);
+ struct v3_intr_state * intr_state = &(info->intr_state);
// PrintDebug("[intr_pending]\n");
if (intr_state->excp_pending == 1) {
uint_t get_intr_number(struct guest_info * info) {
- struct vm_intr * intr_state = &(info->intr_state);
+ struct v3_intr_state * intr_state = &(info->intr_state);
if (intr_state->excp_pending == 1) {
return intr_state->excp_num;
intr_type_t get_intr_type(struct guest_info * info) {
- struct vm_intr * intr_state = &(info->intr_state);
+ struct v3_intr_state * intr_state = &(info->intr_state);
if (intr_state->excp_pending) {
PrintDebug("[get_intr_type] Exception\n");
int injecting_intr(struct guest_info * info, uint_t intr_num, intr_type_t type) {
- struct vm_intr * intr_state = &(info->intr_state);
+ struct v3_intr_state * intr_state = &(info->intr_state);
if (type == EXCEPTION) {
PrintDebug("[injecting_intr] Exception\n");
#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;
+}
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
for (i = 0; (i < MAX_PDE32_ENTRIES); i++) {
if (pde[i].present) {
- pte32_t * pte = (pte32_t *)(pde[i].pt_base_addr << PAGE_POWER);
+ // We double cast, first to an addr_t to handle 64 bit issues, then to the pointer
+ pte32_t * pte = (pte32_t *)((addr_t)(pde[i].pt_base_addr << PAGE_POWER));
/*
for (j = 0; (j < MAX_PTE32_ENTRIES); j++) {
pde[i].large_page = 0;
pde[i].global_page = 0;
pde[i].vmm_info = 0;
- pde[i].pt_base_addr = PAGE_ALIGNED_ADDR(pte);
+ pde[i].pt_base_addr = PAGE_ALIGNED_ADDR((addr_t)pte);
}
}
void PrintPDE32(addr_t virtual_address, pde32_t * pde)
{
- PrintDebug("PDE %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, reserved=%x, largePages=%x, globalPage=%x, kernelInfo=%x\n",
+ PrintDebug("PDE %x -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, reserved=%x, largePages=%x, globalPage=%x, kernelInfo=%x\n",
virtual_address,
- (void *) (pde->pt_base_addr << PAGE_POWER),
+ (void *)(addr_t) (pde->pt_base_addr << PAGE_POWER),
pde->present,
pde->writable,
pde->user_page,
{
PrintDebug("PTE %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, dirty=%x, pteAttribute=%x, globalPage=%x, vmm_info=%x\n",
virtual_address,
- (void*)(pte->page_base_addr << PAGE_POWER),
+ (void*)(addr_t)(pte->page_base_addr << PAGE_POWER),
pte->present,
pte->writable,
pte->user_page,
for (i = 0; (i < MAX_PDE32_ENTRIES); i++) {
if (pde[i].present) {
PrintPDE32((addr_t)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), &(pde[i]));
- PrintPT32((addr_t)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), (pte32_t *)(pde[i].pt_base_addr << PAGE_POWER));
+ PrintPT32((addr_t)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), (pte32_t *)(addr_t)(pde[i].pt_base_addr << PAGE_POWER));
}
}
}
pde32_t * shadow_pde = (pde32_t *)&(shadow_pd[PDE32_INDEX(location)]);
if (shadow_pde->large_page == 0) {
- pte32_t * shadow_pt = (pte32_t *)PDE32_T_ADDR((*shadow_pde));
+ pte32_t * shadow_pt = (pte32_t *)(addr_t)PDE32_T_ADDR((*shadow_pde));
pte32_t * shadow_pte = (pte32_t *)&(shadow_pt[PTE32_INDEX(location)]);
//if (shadow_pte->present == 1) {
guest_pde->accessed = 1;
- shadow_pde->pt_base_addr = PD32_BASE_ADDR(shadow_pt);
+ shadow_pde->pt_base_addr = PD32_BASE_ADDR((addr_t)shadow_pt);
if (guest_pde->large_page == 0) {
shadow_pde->writable = guest_pde->writable;
//
// PTE fault
//
- pte32_t * shadow_pt = (pte32_t *)PDE32_T_ADDR((*shadow_pde));
+ pte32_t * shadow_pt = (pte32_t *)(addr_t)PDE32_T_ADDR((*shadow_pde));
if (guest_pde->large_page == 0) {
pte32_t * guest_pt = NULL;
if (info->cpu_mode == PROTECTED) {
- char instr[15];
+ uchar_t instr[15];
int ret;
int index = 0;
} else {
if (shadow_pde->present == 1) {
- pte32_t * shadow_pt = (pte32_t *)PDE32_T_ADDR((*shadow_pde));
+ pte32_t * shadow_pt = (pte32_t *)(addr_t)PDE32_T_ADDR((*shadow_pde));
pte32_t * shadow_pte = (pte32_t *)&shadow_pt[PTE32_INDEX(first_operand)];
#ifdef DEBUG_SHADOW_PAGING
*/
+
+#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>
static float e = 0.00000001;
-double ceil(double x) {
+double v3_ceil(double x) {
if ((double)(x - (int)x) == 0) {
return (int)x;
}
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
+
}
-void PrintTraceMemDump(unsigned char *start, int n)
-{
+void PrintTraceMemDump(uchar_t * start, int n) {
int i, j;
for (i = 0; i < n; i += 16) {
- PrintTrace("%8x", (unsigned)(start + i));
+ PrintTrace("%8x", (start + i));
for (j = i; (j < (i + 16)) && (j < n); j += 2) {
PrintTrace(" ");
- PrintTraceHex(*((unsigned char *)(start + j)));
+ PrintTraceHex(*(uchar_t *)(start + j));
if ((j + 1) < n) {
- PrintTraceHex(*((unsigned char *)(start + j + 1)));
+ PrintTraceHex(*((uchar_t *)(start + j + 1)));
}
}
PrintTrace(" ");
--- /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);
+
+}